late-sdk 0.0.699 → 0.0.701

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/docs/CommentAutomationsApi.md +1 -1
  4. data/docs/CreateCommentAutomation200ResponseAutomation.md +2 -0
  5. data/docs/CreateCommentAutomationRequest.md +2 -0
  6. data/docs/GetCommentAutomation200ResponseAutomation.md +2 -0
  7. data/docs/GetCommentAutomation200ResponseLogsInner.md +2 -0
  8. data/docs/GetInboxConversationMessages200ResponseMessagesInnerAttachmentsInner.md +3 -1
  9. data/docs/GetMessageAttachment200Response.md +22 -0
  10. data/docs/ListCommentAutomations200ResponseAutomationsInner.md +2 -0
  11. data/docs/MessagesApi.md +80 -0
  12. data/docs/UpdateCommentAutomation200ResponseAutomation.md +2 -0
  13. data/docs/UpdateCommentAutomationRequest.md +2 -0
  14. data/lib/zernio-sdk/api/comment_automations_api.rb +2 -2
  15. data/lib/zernio-sdk/api/messages_api.rb +93 -0
  16. data/lib/zernio-sdk/models/create_comment_automation200_response_automation.rb +11 -1
  17. data/lib/zernio-sdk/models/create_comment_automation_request.rb +13 -1
  18. data/lib/zernio-sdk/models/get_comment_automation200_response_automation.rb +11 -1
  19. data/lib/zernio-sdk/models/get_comment_automation200_response_logs_inner.rb +23 -1
  20. data/lib/zernio-sdk/models/get_inbox_conversation_messages200_response_messages_inner_attachments_inner.rb +13 -1
  21. data/lib/zernio-sdk/models/get_message_attachment200_response.rb +167 -0
  22. data/lib/zernio-sdk/models/list_comment_automations200_response_automations_inner.rb +11 -1
  23. data/lib/zernio-sdk/models/update_comment_automation200_response_automation.rb +11 -1
  24. data/lib/zernio-sdk/models/update_comment_automation_request.rb +11 -1
  25. data/lib/zernio-sdk/version.rb +1 -1
  26. data/lib/zernio-sdk.rb +1 -0
  27. data/openapi.yaml +91 -1
  28. data/spec/api/comment_automations_api_spec.rb +1 -1
  29. data/spec/api/messages_api_spec.rb +16 -0
  30. data/spec/models/create_comment_automation200_response_automation_spec.rb +6 -0
  31. data/spec/models/create_comment_automation_request_spec.rb +6 -0
  32. data/spec/models/get_comment_automation200_response_automation_spec.rb +6 -0
  33. data/spec/models/get_comment_automation200_response_logs_inner_spec.rb +10 -0
  34. data/spec/models/get_inbox_conversation_messages200_response_messages_inner_attachments_inner_spec.rb +6 -0
  35. data/spec/models/get_message_attachment200_response_spec.rb +48 -0
  36. data/spec/models/list_comment_automations200_response_automations_inner_spec.rb +6 -0
  37. data/spec/models/update_comment_automation200_response_automation_spec.rb +6 -0
  38. data/spec/models/update_comment_automation_request_spec.rb +6 -0
  39. data/zernio-sdk-0.0.701.gem +0 -0
  40. metadata +6 -2
  41. data/zernio-sdk-0.0.699.gem +0 -0
@@ -25,6 +25,9 @@ module Zernio
25
25
 
26
26
  attr_accessor :comment_text
27
27
 
28
+ # Which door triggered this send. Absent on rows written before this field existed (all of those are comment-triggered).
29
+ attr_accessor :source
30
+
28
31
  # DM outcome. 'pending' = the automation has a dmDelaySeconds and the response is queued but not sent yet. 'gated' = the follow-gate confirmation DM went out and we are waiting for the tap; it flips to 'sent' or 'skipped' when they tap.
29
32
  attr_accessor :status
30
33
 
@@ -80,6 +83,7 @@ module Zernio
80
83
  :'commenter_id' => :'commenterId',
81
84
  :'commenter_name' => :'commenterName',
82
85
  :'comment_text' => :'commentText',
86
+ :'source' => :'source',
83
87
  :'status' => :'status',
84
88
  :'audience_outcome' => :'audienceOutcome',
85
89
  :'commenter_is_follower' => :'commenterIsFollower',
@@ -110,6 +114,7 @@ module Zernio
110
114
  :'commenter_id' => :'String',
111
115
  :'commenter_name' => :'String',
112
116
  :'comment_text' => :'String',
117
+ :'source' => :'String',
113
118
  :'status' => :'String',
114
119
  :'audience_outcome' => :'String',
115
120
  :'commenter_is_follower' => :'Boolean',
@@ -164,6 +169,10 @@ module Zernio
164
169
  self.comment_text = attributes[:'comment_text']
165
170
  end
166
171
 
172
+ if attributes.key?(:'source')
173
+ self.source = attributes[:'source']
174
+ end
175
+
167
176
  if attributes.key?(:'status')
168
177
  self.status = attributes[:'status']
169
178
  end
@@ -213,6 +222,8 @@ module Zernio
213
222
  # @return true if the model is valid
214
223
  def valid?
215
224
  warn '[DEPRECATED] the `valid?` method is obsolete'
225
+ source_validator = EnumAttributeValidator.new('String', ["comment", "story_reply", "dm"])
226
+ return false unless source_validator.valid?(@source)
216
227
  status_validator = EnumAttributeValidator.new('String', ["pending", "sent", "failed", "skipped", "gated"])
217
228
  return false unless status_validator.valid?(@status)
218
229
  audience_outcome_validator = EnumAttributeValidator.new('String', ["passed", "blocked", "gate_sent", "gate_passed", "gate_failed"])
@@ -222,6 +233,16 @@ module Zernio
222
233
  true
223
234
  end
224
235
 
236
+ # Custom attribute writer method checking allowed values (enum).
237
+ # @param [Object] source Object to be assigned
238
+ def source=(source)
239
+ validator = EnumAttributeValidator.new('String', ["comment", "story_reply", "dm"])
240
+ unless validator.valid?(source)
241
+ fail ArgumentError, "invalid value for \"source\", must be one of #{validator.allowable_values}."
242
+ end
243
+ @source = source
244
+ end
245
+
225
246
  # Custom attribute writer method checking allowed values (enum).
226
247
  # @param [Object] status Object to be assigned
227
248
  def status=(status)
@@ -262,6 +283,7 @@ module Zernio
262
283
  commenter_id == o.commenter_id &&
263
284
  commenter_name == o.commenter_name &&
264
285
  comment_text == o.comment_text &&
286
+ source == o.source &&
265
287
  status == o.status &&
266
288
  audience_outcome == o.audience_outcome &&
267
289
  commenter_is_follower == o.commenter_is_follower &&
@@ -282,7 +304,7 @@ module Zernio
282
304
  # Calculates hash code according to all attributes.
283
305
  # @return [Integer] Hash code
284
306
  def hash
285
- [id, comment_id, commenter_id, commenter_name, comment_text, status, audience_outcome, commenter_is_follower, commenter_follower_count, error, comment_reply_status, comment_reply_error, next_due_at, created_at].hash
307
+ [id, comment_id, commenter_id, commenter_name, comment_text, source, status, audience_outcome, commenter_is_follower, commenter_follower_count, error, comment_reply_status, comment_reply_error, next_due_at, created_at].hash
286
308
  end
287
309
 
288
310
  # Builds the object from hash
@@ -19,8 +19,12 @@ module Zernio
19
19
 
20
20
  attr_accessor :type
21
21
 
22
+ # Direct media link. On Instagram and Facebook this is a signed Meta CDN url that EXPIRES: use it now, do not store it. Persist `refreshUrl` instead.
22
23
  attr_accessor :url
23
24
 
25
+ # Instagram and Facebook only. Endpoint that resolves this attachment to a working url every time, re-minting it from Meta when the stored one has expired. Safe to store and render indefinitely.
26
+ attr_accessor :refresh_url
27
+
24
28
  attr_accessor :filename
25
29
 
26
30
  attr_accessor :preview_url
@@ -53,6 +57,7 @@ module Zernio
53
57
  :'id' => :'id',
54
58
  :'type' => :'type',
55
59
  :'url' => :'url',
60
+ :'refresh_url' => :'refreshUrl',
56
61
  :'filename' => :'filename',
57
62
  :'preview_url' => :'previewUrl'
58
63
  }
@@ -74,6 +79,7 @@ module Zernio
74
79
  :'id' => :'String',
75
80
  :'type' => :'String',
76
81
  :'url' => :'String',
82
+ :'refresh_url' => :'String',
77
83
  :'filename' => :'String',
78
84
  :'preview_url' => :'String'
79
85
  }
@@ -82,6 +88,7 @@ module Zernio
82
88
  # List of attributes with nullable: true
83
89
  def self.openapi_nullable
84
90
  Set.new([
91
+ :'refresh_url',
85
92
  :'filename',
86
93
  :'preview_url'
87
94
  ])
@@ -115,6 +122,10 @@ module Zernio
115
122
  self.url = attributes[:'url']
116
123
  end
117
124
 
125
+ if attributes.key?(:'refresh_url')
126
+ self.refresh_url = attributes[:'refresh_url']
127
+ end
128
+
118
129
  if attributes.key?(:'filename')
119
130
  self.filename = attributes[:'filename']
120
131
  end
@@ -159,6 +170,7 @@ module Zernio
159
170
  id == o.id &&
160
171
  type == o.type &&
161
172
  url == o.url &&
173
+ refresh_url == o.refresh_url &&
162
174
  filename == o.filename &&
163
175
  preview_url == o.preview_url
164
176
  end
@@ -172,7 +184,7 @@ module Zernio
172
184
  # Calculates hash code according to all attributes.
173
185
  # @return [Integer] Hash code
174
186
  def hash
175
- [id, type, url, filename, preview_url].hash
187
+ [id, type, url, refresh_url, filename, preview_url].hash
176
188
  end
177
189
 
178
190
  # Builds the object from hash
@@ -0,0 +1,167 @@
1
+ =begin
2
+ #Zernio API
3
+
4
+ #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api
5
+
6
+ The version of the OpenAPI document: 1.0.4
7
+ Contact: support@zernio.com
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 Zernio
17
+ class GetMessageAttachment200Response < ApiModelBase
18
+ attr_accessor :status
19
+
20
+ # Live media url. Short-lived; re-request this endpoint rather than storing it.
21
+ attr_accessor :url
22
+
23
+ # True when the stored url had expired and was re-minted from the platform.
24
+ attr_accessor :refreshed
25
+
26
+ # Attribute mapping from ruby-style variable name to JSON key.
27
+ def self.attribute_map
28
+ {
29
+ :'status' => :'status',
30
+ :'url' => :'url',
31
+ :'refreshed' => :'refreshed'
32
+ }
33
+ end
34
+
35
+ # Returns attribute mapping this model knows about
36
+ def self.acceptable_attribute_map
37
+ attribute_map
38
+ end
39
+
40
+ # Returns all the JSON keys this model knows about
41
+ def self.acceptable_attributes
42
+ acceptable_attribute_map.values
43
+ end
44
+
45
+ # Attribute type mapping.
46
+ def self.openapi_types
47
+ {
48
+ :'status' => :'String',
49
+ :'url' => :'String',
50
+ :'refreshed' => :'Boolean'
51
+ }
52
+ end
53
+
54
+ # List of attributes with nullable: true
55
+ def self.openapi_nullable
56
+ Set.new([
57
+ ])
58
+ end
59
+
60
+ # Initializes the object
61
+ # @param [Hash] attributes Model attributes in the form of hash
62
+ def initialize(attributes = {})
63
+ if (!attributes.is_a?(Hash))
64
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Zernio::GetMessageAttachment200Response` initialize method"
65
+ end
66
+
67
+ # check to see if the attribute exists and convert string to symbol for hash key
68
+ acceptable_attribute_map = self.class.acceptable_attribute_map
69
+ attributes = attributes.each_with_object({}) { |(k, v), h|
70
+ if (!acceptable_attribute_map.key?(k.to_sym))
71
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Zernio::GetMessageAttachment200Response`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
72
+ end
73
+ h[k.to_sym] = v
74
+ }
75
+
76
+ if attributes.key?(:'status')
77
+ self.status = attributes[:'status']
78
+ end
79
+
80
+ if attributes.key?(:'url')
81
+ self.url = attributes[:'url']
82
+ end
83
+
84
+ if attributes.key?(:'refreshed')
85
+ self.refreshed = attributes[:'refreshed']
86
+ end
87
+ end
88
+
89
+ # Show invalid properties with the reasons. Usually used together with valid?
90
+ # @return Array for valid properties with the reasons
91
+ def list_invalid_properties
92
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
93
+ invalid_properties = Array.new
94
+ invalid_properties
95
+ end
96
+
97
+ # Check to see if the all the properties in the model are valid
98
+ # @return true if the model is valid
99
+ def valid?
100
+ warn '[DEPRECATED] the `valid?` method is obsolete'
101
+ true
102
+ end
103
+
104
+ # Checks equality by comparing each attribute.
105
+ # @param [Object] Object to be compared
106
+ def ==(o)
107
+ return true if self.equal?(o)
108
+ self.class == o.class &&
109
+ status == o.status &&
110
+ url == o.url &&
111
+ refreshed == o.refreshed
112
+ end
113
+
114
+ # @see the `==` method
115
+ # @param [Object] Object to be compared
116
+ def eql?(o)
117
+ self == o
118
+ end
119
+
120
+ # Calculates hash code according to all attributes.
121
+ # @return [Integer] Hash code
122
+ def hash
123
+ [status, url, refreshed].hash
124
+ end
125
+
126
+ # Builds the object from hash
127
+ # @param [Hash] attributes Model attributes in the form of hash
128
+ # @return [Object] Returns the model itself
129
+ def self.build_from_hash(attributes)
130
+ return nil unless attributes.is_a?(Hash)
131
+ attributes = attributes.transform_keys(&:to_sym)
132
+ transformed_hash = {}
133
+ openapi_types.each_pair do |key, type|
134
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
135
+ transformed_hash["#{key}"] = nil
136
+ elsif type =~ /\AArray<(.*)>/i
137
+ # check to ensure the input is an array given that the attribute
138
+ # is documented as an array but the input is not
139
+ if attributes[attribute_map[key]].is_a?(Array)
140
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
141
+ end
142
+ elsif !attributes[attribute_map[key]].nil?
143
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
144
+ end
145
+ end
146
+ new(transformed_hash)
147
+ end
148
+
149
+ # Returns the object in the form of hash
150
+ # @return [Hash] Returns the object in the form of hash
151
+ def to_hash
152
+ hash = {}
153
+ self.class.attribute_map.each_pair do |attr, param|
154
+ value = self.send(attr)
155
+ if value.nil?
156
+ is_nullable = self.class.openapi_nullable.include?(attr)
157
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
158
+ end
159
+
160
+ hash[param] = _to_hash(value)
161
+ end
162
+ hash
163
+ end
164
+
165
+ end
166
+
167
+ end
@@ -67,6 +67,9 @@ module Zernio
67
67
  # Seconds waited before the public reply is posted. Absent when it follows the DM immediately.
68
68
  attr_accessor :comment_reply_delay_seconds
69
69
 
70
+ # Whether these keywords also fire on a plain inbound DM.
71
+ attr_accessor :also_match_in_dms
72
+
70
73
  attr_accessor :is_active
71
74
 
72
75
  attr_accessor :stats
@@ -119,6 +122,7 @@ module Zernio
119
122
  :'click_tag' => :'clickTag',
120
123
  :'dm_delay_seconds' => :'dmDelaySeconds',
121
124
  :'comment_reply_delay_seconds' => :'commentReplyDelaySeconds',
125
+ :'also_match_in_dms' => :'alsoMatchInDms',
122
126
  :'is_active' => :'isActive',
123
127
  :'stats' => :'stats',
124
128
  :'created_at' => :'createdAt'
@@ -159,6 +163,7 @@ module Zernio
159
163
  :'click_tag' => :'String',
160
164
  :'dm_delay_seconds' => :'Integer',
161
165
  :'comment_reply_delay_seconds' => :'Integer',
166
+ :'also_match_in_dms' => :'Boolean',
162
167
  :'is_active' => :'Boolean',
163
168
  :'stats' => :'ListCommentAutomations200ResponseAutomationsInnerStats',
164
169
  :'created_at' => :'Time'
@@ -281,6 +286,10 @@ module Zernio
281
286
  self.comment_reply_delay_seconds = attributes[:'comment_reply_delay_seconds']
282
287
  end
283
288
 
289
+ if attributes.key?(:'also_match_in_dms')
290
+ self.also_match_in_dms = attributes[:'also_match_in_dms']
291
+ end
292
+
284
293
  if attributes.key?(:'is_active')
285
294
  self.is_active = attributes[:'is_active']
286
295
  end
@@ -371,6 +380,7 @@ module Zernio
371
380
  click_tag == o.click_tag &&
372
381
  dm_delay_seconds == o.dm_delay_seconds &&
373
382
  comment_reply_delay_seconds == o.comment_reply_delay_seconds &&
383
+ also_match_in_dms == o.also_match_in_dms &&
374
384
  is_active == o.is_active &&
375
385
  stats == o.stats &&
376
386
  created_at == o.created_at
@@ -385,7 +395,7 @@ module Zernio
385
395
  # Calculates hash code according to all attributes.
386
396
  # @return [Integer] Hash code
387
397
  def hash
388
- [id, name, platform, trigger, account_id, platform_post_id, post_title, keywords, match_mode, exclude_keywords, typo_tolerance, dm_message, buttons, template, comment_reply, dm_message_variations, comment_reply_variations, link_tracking, click_tag, dm_delay_seconds, comment_reply_delay_seconds, is_active, stats, created_at].hash
398
+ [id, name, platform, trigger, account_id, platform_post_id, post_title, keywords, match_mode, exclude_keywords, typo_tolerance, dm_message, buttons, template, comment_reply, dm_message_variations, comment_reply_variations, link_tracking, click_tag, dm_delay_seconds, comment_reply_delay_seconds, also_match_in_dms, is_active, stats, created_at].hash
389
399
  end
390
400
 
391
401
  # Builds the object from hash
@@ -49,6 +49,9 @@ module Zernio
49
49
 
50
50
  attr_accessor :follow_gate
51
51
 
52
+ # Whether these keywords also fire on a plain inbound DM.
53
+ attr_accessor :also_match_in_dms
54
+
52
55
  attr_accessor :is_active
53
56
 
54
57
  attr_accessor :updated_at
@@ -92,6 +95,7 @@ module Zernio
92
95
  :'comment_reply_variations' => :'commentReplyVariations',
93
96
  :'audience' => :'audience',
94
97
  :'follow_gate' => :'followGate',
98
+ :'also_match_in_dms' => :'alsoMatchInDms',
95
99
  :'is_active' => :'isActive',
96
100
  :'updated_at' => :'updatedAt'
97
101
  }
@@ -124,6 +128,7 @@ module Zernio
124
128
  :'comment_reply_variations' => :'Array<String>',
125
129
  :'audience' => :'CommentAutomationAudience',
126
130
  :'follow_gate' => :'CommentAutomationFollowGate',
131
+ :'also_match_in_dms' => :'Boolean',
127
132
  :'is_active' => :'Boolean',
128
133
  :'updated_at' => :'Time'
129
134
  }
@@ -218,6 +223,10 @@ module Zernio
218
223
  self.follow_gate = attributes[:'follow_gate']
219
224
  end
220
225
 
226
+ if attributes.key?(:'also_match_in_dms')
227
+ self.also_match_in_dms = attributes[:'also_match_in_dms']
228
+ end
229
+
221
230
  if attributes.key?(:'is_active')
222
231
  self.is_active = attributes[:'is_active']
223
232
  end
@@ -273,6 +282,7 @@ module Zernio
273
282
  comment_reply_variations == o.comment_reply_variations &&
274
283
  audience == o.audience &&
275
284
  follow_gate == o.follow_gate &&
285
+ also_match_in_dms == o.also_match_in_dms &&
276
286
  is_active == o.is_active &&
277
287
  updated_at == o.updated_at
278
288
  end
@@ -286,7 +296,7 @@ module Zernio
286
296
  # Calculates hash code according to all attributes.
287
297
  # @return [Integer] Hash code
288
298
  def hash
289
- [id, name, keywords, match_mode, exclude_keywords, typo_tolerance, dm_message, buttons, template, comment_reply, dm_message_variations, comment_reply_variations, audience, follow_gate, is_active, updated_at].hash
299
+ [id, name, keywords, match_mode, exclude_keywords, typo_tolerance, dm_message, buttons, template, comment_reply, dm_message_variations, comment_reply_variations, audience, follow_gate, also_match_in_dms, is_active, updated_at].hash
290
300
  end
291
301
 
292
302
  # Builds the object from hash
@@ -52,6 +52,9 @@ module Zernio
52
52
  # Tag applied to a contact when they click a tracked link (requires linkTracking). Empty string clears it.
53
53
  attr_accessor :click_tag
54
54
 
55
+ # Also fire these keywords on a plain inbound DM. Enabling it requires the automation to end up with at least one keyword (this request's keywords if you send them, otherwise the stored ones) and is rejected on story_reply automations.
56
+ attr_accessor :also_match_in_dms
57
+
55
58
  # Seconds to wait after the trigger before sending the DM. Send 0 to clear the delay and reply immediately.
56
59
  attr_accessor :dm_delay_seconds
57
60
 
@@ -103,6 +106,7 @@ module Zernio
103
106
  :'comment_reply_variations' => :'commentReplyVariations',
104
107
  :'link_tracking' => :'linkTracking',
105
108
  :'click_tag' => :'clickTag',
109
+ :'also_match_in_dms' => :'alsoMatchInDms',
106
110
  :'dm_delay_seconds' => :'dmDelaySeconds',
107
111
  :'comment_reply_delay_seconds' => :'commentReplyDelaySeconds',
108
112
  :'audience' => :'audience',
@@ -138,6 +142,7 @@ module Zernio
138
142
  :'comment_reply_variations' => :'Array<String>',
139
143
  :'link_tracking' => :'Boolean',
140
144
  :'click_tag' => :'String',
145
+ :'also_match_in_dms' => :'Boolean',
141
146
  :'dm_delay_seconds' => :'Integer',
142
147
  :'comment_reply_delay_seconds' => :'Integer',
143
148
  :'audience' => :'CommentAutomationAudience',
@@ -235,6 +240,10 @@ module Zernio
235
240
  self.click_tag = attributes[:'click_tag']
236
241
  end
237
242
 
243
+ if attributes.key?(:'also_match_in_dms')
244
+ self.also_match_in_dms = attributes[:'also_match_in_dms']
245
+ end
246
+
238
247
  if attributes.key?(:'dm_delay_seconds')
239
248
  self.dm_delay_seconds = attributes[:'dm_delay_seconds']
240
249
  end
@@ -427,6 +436,7 @@ module Zernio
427
436
  comment_reply_variations == o.comment_reply_variations &&
428
437
  link_tracking == o.link_tracking &&
429
438
  click_tag == o.click_tag &&
439
+ also_match_in_dms == o.also_match_in_dms &&
430
440
  dm_delay_seconds == o.dm_delay_seconds &&
431
441
  comment_reply_delay_seconds == o.comment_reply_delay_seconds &&
432
442
  audience == o.audience &&
@@ -443,7 +453,7 @@ module Zernio
443
453
  # Calculates hash code according to all attributes.
444
454
  # @return [Integer] Hash code
445
455
  def hash
446
- [name, trigger, keywords, match_mode, exclude_keywords, typo_tolerance, dm_message, buttons, template, comment_reply, dm_message_variations, comment_reply_variations, link_tracking, click_tag, dm_delay_seconds, comment_reply_delay_seconds, audience, follow_gate, is_active].hash
456
+ [name, trigger, keywords, match_mode, exclude_keywords, typo_tolerance, dm_message, buttons, template, comment_reply, dm_message_variations, comment_reply_variations, link_tracking, click_tag, also_match_in_dms, dm_delay_seconds, comment_reply_delay_seconds, audience, follow_gate, is_active].hash
447
457
  end
448
458
 
449
459
  # Builds the object from hash
@@ -11,5 +11,5 @@ Generator version: 7.19.0
11
11
  =end
12
12
 
13
13
  module Zernio
14
- VERSION = '0.0.699'
14
+ VERSION = '0.0.701'
15
15
  end
data/lib/zernio-sdk.rb CHANGED
@@ -629,6 +629,7 @@ require 'zernio-sdk/models/get_linked_in_supply_forecast_request'
629
629
  require 'zernio-sdk/models/get_linked_in_supply_forecast_request_competing_bid'
630
630
  require 'zernio-sdk/models/get_media_presigned_url200_response'
631
631
  require 'zernio-sdk/models/get_media_presigned_url_request'
632
+ require 'zernio-sdk/models/get_message_attachment200_response'
632
633
  require 'zernio-sdk/models/get_messenger_menu200_response'
633
634
  require 'zernio-sdk/models/get_pending_o_auth_data200_response'
634
635
  require 'zernio-sdk/models/get_pending_o_auth_data200_response_organizations_inner'
data/openapi.yaml CHANGED
@@ -24390,7 +24390,12 @@ paths:
24390
24390
  properties:
24391
24391
  id: { type: string }
24392
24392
  type: { type: string, enum: [image, video, audio, file, sticker, share] }
24393
- url: { type: string }
24393
+ url:
24394
+ type: string
24395
+ description: 'Direct media link. On Instagram and Facebook this is a signed Meta CDN url that EXPIRES: use it now, do not store it. Persist `refreshUrl` instead.'
24396
+ refreshUrl:
24397
+ type: [string, "null"]
24398
+ description: 'Instagram and Facebook only. Endpoint that resolves this attachment to a working url every time, re-minting it from Meta when the stored one has expired. Safe to store and render indefinitely.'
24394
24399
  filename: { type: [string, "null"] }
24395
24400
  previewUrl: { type: [string, "null"] }
24396
24401
  subject: { type: [string, "null"], description: Reddit message subject }
@@ -25660,6 +25665,77 @@ paths:
25660
25665
  '400': { $ref: '#/components/responses/BadRequest' }
25661
25666
  '401': { $ref: '#/components/responses/Unauthorized' }
25662
25667
 
25668
+ /v1/inbox/conversations/{conversationId}/messages/{messageId}/attachments/{index}:
25669
+ get:
25670
+ x-resource-group: "messages"
25671
+ operationId: getMessageAttachment
25672
+ summary: Resolve message attachment
25673
+ description: |
25674
+ Resolve one attachment on a message to a media url that works right now.
25675
+
25676
+ Instagram and Facebook sign DM media urls per request and expire them, so
25677
+ the `url` on a message is a snapshot: it works when you read the message
25678
+ and stops working later. This endpoint checks the stored url and, when it
25679
+ has gone stale, re-mints the message's media from Meta and persists it
25680
+ before answering. The message id never expires, so this URL is the one to
25681
+ store — it is returned on each attachment as `refreshUrl`.
25682
+
25683
+ By default it responds `302` to the live media url, so it can be used
25684
+ directly as an `<img src>` on a browser session. API-key integrators
25685
+ should pass `?format=json` and read `url` off the body, since a browser
25686
+ cannot attach an Authorization header to an image request.
25687
+
25688
+ Only Instagram and Facebook media can be re-minted. On other platforms
25689
+ the stored url is returned as-is when it still resolves, and `404`
25690
+ otherwise.
25691
+ tags: [Messages]
25692
+ security: [{ bearerAuth: [] }]
25693
+ parameters:
25694
+ - name: conversationId
25695
+ in: path
25696
+ required: true
25697
+ schema: { type: string }
25698
+ description: 'The conversation ID (Zernio id or platform conversation id)'
25699
+ - name: messageId
25700
+ in: path
25701
+ required: true
25702
+ schema: { type: string }
25703
+ description: 'The message id as returned by the list-messages endpoint (the platform message id)'
25704
+ - name: index
25705
+ in: path
25706
+ required: true
25707
+ schema: { type: integer, minimum: 0 }
25708
+ description: 'Zero-based position of the attachment in the message''s attachments array'
25709
+ - name: accountId
25710
+ in: query
25711
+ required: true
25712
+ schema: { type: string }
25713
+ description: Social account ID
25714
+ - name: format
25715
+ in: query
25716
+ required: false
25717
+ schema: { type: string, enum: [redirect, json], default: redirect }
25718
+ description: '`redirect` (default) answers 302 to the media; `json` returns the url in the body'
25719
+ responses:
25720
+ '200':
25721
+ description: 'Resolved url (only when format=json)'
25722
+ content:
25723
+ application/json:
25724
+ schema:
25725
+ type: object
25726
+ properties:
25727
+ status: { type: string, example: success }
25728
+ url: { type: string, description: 'Live media url. Short-lived; re-request this endpoint rather than storing it.' }
25729
+ refreshed: { type: boolean, description: True when the stored url had expired and was re-minted from the platform. }
25730
+ '302':
25731
+ description: Redirect to the live media url
25732
+ '400': { $ref: '#/components/responses/BadRequest' }
25733
+ '401': { $ref: '#/components/responses/Unauthorized' }
25734
+ '403':
25735
+ description: Inbox addon required
25736
+ '404':
25737
+ description: 'Account, conversation, message or attachment not found, or the platform no longer serves the media'
25738
+
25663
25739
  /v1/inbox/comments:
25664
25740
  get:
25665
25741
  x-resource-group: "engagement"
@@ -36147,6 +36223,7 @@ paths:
36147
36223
  clickTag: { type: string, description: "Tag applied to a contact when they click a tracked link." }
36148
36224
  dmDelaySeconds: { type: integer, description: "Seconds waited after the trigger before the DM is sent. Absent when the DM goes out immediately." }
36149
36225
  commentReplyDelaySeconds: { type: integer, description: "Seconds waited before the public reply is posted. Absent when it follows the DM immediately." }
36226
+ alsoMatchInDms: { type: boolean, description: "Whether these keywords also fire on a plain inbound DM." }
36150
36227
  isActive: { type: boolean }
36151
36228
  stats:
36152
36229
  type: object
@@ -36194,6 +36271,12 @@ paths:
36194
36271
  confirmation DM (`followGate`) and then delivers the real DM automatically. People we
36195
36272
  already know follow you skip the tap entirely.
36196
36273
 
36274
+ Set `alsoMatchInDms: true` on a `comment` automation to also answer people who send
36275
+ a keyword as a direct message instead of commenting it. One automation then covers
36276
+ both doors, and each door is deduplicated separately (someone who already got the DM
36277
+ from their comment still gets it if they later DM the keyword). Requires at least one
36278
+ keyword.
36279
+
36197
36280
  Links in the DM's buttons can be click-tracked (`linkTracking`, on by default) and
36198
36281
  clickers optionally tagged (`clickTag`) for segmentation. Stats returned include
36199
36282
  delivered, read, and link clicks.
@@ -36245,6 +36328,7 @@ paths:
36245
36328
  clickTag: { type: string, description: "Optional tag applied to a contact when they click a tracked link (requires linkTracking). Lets you segment clickers for broadcasts/sequences." }
36246
36329
  dmDelaySeconds: { type: integer, minimum: 0, maximum: 86400, description: "Seconds to wait after the trigger before sending the DM. Omit or send 0 to reply immediately (the default). Max 86400 (24h). The trigger is still matched and deduplicated the moment the comment arrives, so a delay only moves when the response is sent." }
36247
36330
  commentReplyDelaySeconds: { type: integer, minimum: 0, maximum: 86400, description: "Seconds to wait before posting the public comment reply. Omit or send 0 to post it right after the DM (the default). The reply never goes out before the DM, so a value below dmDelaySeconds is raised to it. Ignored when trigger=story_reply, which has no public reply." }
36331
+ alsoMatchInDms: { type: boolean, default: false, description: "Also fire these keywords on a plain inbound DM, so the automation answers people who message the keyword instead of commenting it. Requires at least one keyword (an empty keyword list means 'match anything', which would answer every inbound message) and is rejected on story_reply automations, which already trigger on DMs. Dedup is per door: a contact who already received the DM from their comment can still receive it from a DM." }
36248
36332
  audience: { $ref: '#/components/schemas/CommentAutomationAudience' }
36249
36333
  followGate: { $ref: '#/components/schemas/CommentAutomationFollowGate' }
36250
36334
  responses:
@@ -36284,6 +36368,7 @@ paths:
36284
36368
  commentReplyDelaySeconds: { type: integer, description: "Seconds waited before the public reply is posted. Absent when it follows the DM immediately." }
36285
36369
  audience: { $ref: '#/components/schemas/CommentAutomationAudience' }
36286
36370
  followGate: { $ref: '#/components/schemas/CommentAutomationFollowGate' }
36371
+ alsoMatchInDms: { type: boolean, description: "Whether these keywords also fire on a plain inbound DM." }
36287
36372
  isActive: { type: boolean }
36288
36373
  stats: { type: object, properties: { totalTriggered: { type: integer }, totalSent: { type: integer }, totalFailed: { type: integer } } }
36289
36374
  createdAt: { type: string, format: date-time }
@@ -36342,6 +36427,7 @@ paths:
36342
36427
  commentReplyDelaySeconds: { type: integer, description: "Seconds waited before the public reply is posted. Absent when it follows the DM immediately." }
36343
36428
  audience: { $ref: '#/components/schemas/CommentAutomationAudience' }
36344
36429
  followGate: { $ref: '#/components/schemas/CommentAutomationFollowGate' }
36430
+ alsoMatchInDms: { type: boolean, description: "Whether these keywords also fire on a plain inbound DM." }
36345
36431
  isActive: { type: boolean }
36346
36432
  stats: { type: object, properties: { totalTriggered: { type: integer }, totalSent: { type: integer }, totalFailed: { type: integer } } }
36347
36433
  createdAt: { type: string, format: date-time }
@@ -36356,6 +36442,7 @@ paths:
36356
36442
  commenterId: { type: string }
36357
36443
  commenterName: { type: string }
36358
36444
  commentText: { type: string }
36445
+ source: { type: string, enum: [comment, story_reply, dm], description: "Which door triggered this send. Absent on rows written before this field existed (all of those are comment-triggered)." }
36359
36446
  status: { type: string, enum: [pending, sent, failed, skipped, gated], description: "DM outcome. 'pending' = the automation has a dmDelaySeconds and the response is queued but not sent yet. 'gated' = the follow-gate confirmation DM went out and we are waiting for the tap; it flips to 'sent' or 'skipped' when they tap." }
36360
36447
  audienceOutcome: { type: string, enum: [passed, blocked, gate_sent, gate_passed, gate_failed], description: "How the audience rule resolved. Absent on automations without one." }
36361
36448
  commenterIsFollower: { type: boolean, description: "Follow relationship at decision time. Absent when Instagram would not tell us (the commenter never messaged the account)." }
@@ -36416,6 +36503,7 @@ paths:
36416
36503
  description: "Alternate public replies for random rotation. Pass [] to clear."
36417
36504
  linkTracking: { type: boolean, description: "Wrap link buttons in a tracked redirect to count clicks. Pass false to send links untouched." }
36418
36505
  clickTag: { type: string, description: "Tag applied to a contact when they click a tracked link (requires linkTracking). Empty string clears it." }
36506
+ alsoMatchInDms: { type: boolean, description: "Also fire these keywords on a plain inbound DM. Enabling it requires the automation to end up with at least one keyword (this request's keywords if you send them, otherwise the stored ones) and is rejected on story_reply automations." }
36419
36507
  dmDelaySeconds: { type: integer, minimum: 0, maximum: 86400, description: "Seconds to wait after the trigger before sending the DM. Send 0 to clear the delay and reply immediately." }
36420
36508
  commentReplyDelaySeconds: { type: integer, minimum: 0, maximum: 86400, description: "Seconds to wait before posting the public comment reply. Send 0 to clear it. The reply never goes out before the DM." }
36421
36509
  audience: { $ref: '#/components/schemas/CommentAutomationAudience' }
@@ -36451,6 +36539,7 @@ paths:
36451
36539
  commentReplyVariations: { type: array, items: { type: string }, description: "Alternate public replies rotated at random with commentReply. Omitted when none." }
36452
36540
  audience: { $ref: '#/components/schemas/CommentAutomationAudience' }
36453
36541
  followGate: { $ref: '#/components/schemas/CommentAutomationFollowGate' }
36542
+ alsoMatchInDms: { type: boolean, description: "Whether these keywords also fire on a plain inbound DM." }
36454
36543
  isActive: { type: boolean }
36455
36544
  updatedAt: { type: string, format: date-time }
36456
36545
  '401': { $ref: '#/components/responses/Unauthorized' }
@@ -36503,6 +36592,7 @@ paths:
36503
36592
  commenterId: { type: string }
36504
36593
  commenterName: { type: string }
36505
36594
  commentText: { type: string }
36595
+ source: { type: string, enum: [comment, story_reply, dm], description: "Which door triggered this send. Absent on rows written before this field existed (all of those are comment-triggered)." }
36506
36596
  status: { type: string, enum: [pending, sent, failed, skipped, gated], description: "DM outcome. 'pending' = the automation has a dmDelaySeconds and the response is queued but not sent yet. 'gated' = the follow-gate confirmation DM went out and we are waiting for the tap; it flips to 'sent' or 'skipped' when they tap." }
36507
36597
  audienceOutcome: { type: string, enum: [passed, blocked, gate_sent, gate_passed, gate_failed], description: "How the audience rule resolved. Absent on automations without one." }
36508
36598
  commenterIsFollower: { type: boolean, description: "Follow relationship at decision time. Absent when Instagram would not tell us (the commenter never messaged the account)." }