late-sdk 0.0.87 → 0.0.89

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.
@@ -0,0 +1,165 @@
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.1
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 Late
17
+ class SendTypingIndicatorRequest < ApiModelBase
18
+ # Social account ID
19
+ attr_accessor :account_id
20
+
21
+ # Attribute mapping from ruby-style variable name to JSON key.
22
+ def self.attribute_map
23
+ {
24
+ :'account_id' => :'accountId'
25
+ }
26
+ end
27
+
28
+ # Returns attribute mapping this model knows about
29
+ def self.acceptable_attribute_map
30
+ attribute_map
31
+ end
32
+
33
+ # Returns all the JSON keys this model knows about
34
+ def self.acceptable_attributes
35
+ acceptable_attribute_map.values
36
+ end
37
+
38
+ # Attribute type mapping.
39
+ def self.openapi_types
40
+ {
41
+ :'account_id' => :'String'
42
+ }
43
+ end
44
+
45
+ # List of attributes with nullable: true
46
+ def self.openapi_nullable
47
+ Set.new([
48
+ ])
49
+ end
50
+
51
+ # Initializes the object
52
+ # @param [Hash] attributes Model attributes in the form of hash
53
+ def initialize(attributes = {})
54
+ if (!attributes.is_a?(Hash))
55
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Late::SendTypingIndicatorRequest` initialize method"
56
+ end
57
+
58
+ # check to see if the attribute exists and convert string to symbol for hash key
59
+ acceptable_attribute_map = self.class.acceptable_attribute_map
60
+ attributes = attributes.each_with_object({}) { |(k, v), h|
61
+ if (!acceptable_attribute_map.key?(k.to_sym))
62
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Late::SendTypingIndicatorRequest`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
63
+ end
64
+ h[k.to_sym] = v
65
+ }
66
+
67
+ if attributes.key?(:'account_id')
68
+ self.account_id = attributes[:'account_id']
69
+ else
70
+ self.account_id = nil
71
+ end
72
+ end
73
+
74
+ # Show invalid properties with the reasons. Usually used together with valid?
75
+ # @return Array for valid properties with the reasons
76
+ def list_invalid_properties
77
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
78
+ invalid_properties = Array.new
79
+ if @account_id.nil?
80
+ invalid_properties.push('invalid value for "account_id", account_id cannot be nil.')
81
+ end
82
+
83
+ invalid_properties
84
+ end
85
+
86
+ # Check to see if the all the properties in the model are valid
87
+ # @return true if the model is valid
88
+ def valid?
89
+ warn '[DEPRECATED] the `valid?` method is obsolete'
90
+ return false if @account_id.nil?
91
+ true
92
+ end
93
+
94
+ # Custom attribute writer method with validation
95
+ # @param [Object] account_id Value to be assigned
96
+ def account_id=(account_id)
97
+ if account_id.nil?
98
+ fail ArgumentError, 'account_id cannot be nil'
99
+ end
100
+
101
+ @account_id = account_id
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
+ account_id == o.account_id
110
+ end
111
+
112
+ # @see the `==` method
113
+ # @param [Object] Object to be compared
114
+ def eql?(o)
115
+ self == o
116
+ end
117
+
118
+ # Calculates hash code according to all attributes.
119
+ # @return [Integer] Hash code
120
+ def hash
121
+ [account_id].hash
122
+ end
123
+
124
+ # Builds the object from hash
125
+ # @param [Hash] attributes Model attributes in the form of hash
126
+ # @return [Object] Returns the model itself
127
+ def self.build_from_hash(attributes)
128
+ return nil unless attributes.is_a?(Hash)
129
+ attributes = attributes.transform_keys(&:to_sym)
130
+ transformed_hash = {}
131
+ openapi_types.each_pair do |key, type|
132
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
133
+ transformed_hash["#{key}"] = nil
134
+ elsif type =~ /\AArray<(.*)>/i
135
+ # check to ensure the input is an array given that the attribute
136
+ # is documented as an array but the input is not
137
+ if attributes[attribute_map[key]].is_a?(Array)
138
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
139
+ end
140
+ elsif !attributes[attribute_map[key]].nil?
141
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
142
+ end
143
+ end
144
+ new(transformed_hash)
145
+ end
146
+
147
+ # Returns the object in the form of hash
148
+ # @return [Hash] Returns the object in the form of hash
149
+ def to_hash
150
+ hash = {}
151
+ self.class.attribute_map.each_pair do |attr, param|
152
+ value = self.send(attr)
153
+ if value.nil?
154
+ is_nullable = self.class.openapi_nullable.include?(attr)
155
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
156
+ end
157
+
158
+ hash[param] = _to_hash(value)
159
+ end
160
+ hash
161
+ end
162
+
163
+ end
164
+
165
+ end
@@ -0,0 +1,178 @@
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.1
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 Late
17
+ class UploadMediaDirect200Response < ApiModelBase
18
+ # Publicly accessible URL for the uploaded file
19
+ attr_accessor :url
20
+
21
+ # Generated unique filename
22
+ attr_accessor :filename
23
+
24
+ # MIME type of the file
25
+ attr_accessor :content_type
26
+
27
+ # File size in bytes
28
+ attr_accessor :size
29
+
30
+ # Attribute mapping from ruby-style variable name to JSON key.
31
+ def self.attribute_map
32
+ {
33
+ :'url' => :'url',
34
+ :'filename' => :'filename',
35
+ :'content_type' => :'contentType',
36
+ :'size' => :'size'
37
+ }
38
+ end
39
+
40
+ # Returns attribute mapping this model knows about
41
+ def self.acceptable_attribute_map
42
+ attribute_map
43
+ end
44
+
45
+ # Returns all the JSON keys this model knows about
46
+ def self.acceptable_attributes
47
+ acceptable_attribute_map.values
48
+ end
49
+
50
+ # Attribute type mapping.
51
+ def self.openapi_types
52
+ {
53
+ :'url' => :'String',
54
+ :'filename' => :'String',
55
+ :'content_type' => :'String',
56
+ :'size' => :'Integer'
57
+ }
58
+ end
59
+
60
+ # List of attributes with nullable: true
61
+ def self.openapi_nullable
62
+ Set.new([
63
+ ])
64
+ end
65
+
66
+ # Initializes the object
67
+ # @param [Hash] attributes Model attributes in the form of hash
68
+ def initialize(attributes = {})
69
+ if (!attributes.is_a?(Hash))
70
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Late::UploadMediaDirect200Response` initialize method"
71
+ end
72
+
73
+ # check to see if the attribute exists and convert string to symbol for hash key
74
+ acceptable_attribute_map = self.class.acceptable_attribute_map
75
+ attributes = attributes.each_with_object({}) { |(k, v), h|
76
+ if (!acceptable_attribute_map.key?(k.to_sym))
77
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Late::UploadMediaDirect200Response`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
78
+ end
79
+ h[k.to_sym] = v
80
+ }
81
+
82
+ if attributes.key?(:'url')
83
+ self.url = attributes[:'url']
84
+ end
85
+
86
+ if attributes.key?(:'filename')
87
+ self.filename = attributes[:'filename']
88
+ end
89
+
90
+ if attributes.key?(:'content_type')
91
+ self.content_type = attributes[:'content_type']
92
+ end
93
+
94
+ if attributes.key?(:'size')
95
+ self.size = attributes[:'size']
96
+ end
97
+ end
98
+
99
+ # Show invalid properties with the reasons. Usually used together with valid?
100
+ # @return Array for valid properties with the reasons
101
+ def list_invalid_properties
102
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
103
+ invalid_properties = Array.new
104
+ invalid_properties
105
+ end
106
+
107
+ # Check to see if the all the properties in the model are valid
108
+ # @return true if the model is valid
109
+ def valid?
110
+ warn '[DEPRECATED] the `valid?` method is obsolete'
111
+ true
112
+ end
113
+
114
+ # Checks equality by comparing each attribute.
115
+ # @param [Object] Object to be compared
116
+ def ==(o)
117
+ return true if self.equal?(o)
118
+ self.class == o.class &&
119
+ url == o.url &&
120
+ filename == o.filename &&
121
+ content_type == o.content_type &&
122
+ size == o.size
123
+ end
124
+
125
+ # @see the `==` method
126
+ # @param [Object] Object to be compared
127
+ def eql?(o)
128
+ self == o
129
+ end
130
+
131
+ # Calculates hash code according to all attributes.
132
+ # @return [Integer] Hash code
133
+ def hash
134
+ [url, filename, content_type, size].hash
135
+ end
136
+
137
+ # Builds the object from hash
138
+ # @param [Hash] attributes Model attributes in the form of hash
139
+ # @return [Object] Returns the model itself
140
+ def self.build_from_hash(attributes)
141
+ return nil unless attributes.is_a?(Hash)
142
+ attributes = attributes.transform_keys(&:to_sym)
143
+ transformed_hash = {}
144
+ openapi_types.each_pair do |key, type|
145
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
146
+ transformed_hash["#{key}"] = nil
147
+ elsif type =~ /\AArray<(.*)>/i
148
+ # check to ensure the input is an array given that the attribute
149
+ # is documented as an array but the input is not
150
+ if attributes[attribute_map[key]].is_a?(Array)
151
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
152
+ end
153
+ elsif !attributes[attribute_map[key]].nil?
154
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
155
+ end
156
+ end
157
+ new(transformed_hash)
158
+ end
159
+
160
+ # Returns the object in the form of hash
161
+ # @return [Hash] Returns the object in the form of hash
162
+ def to_hash
163
+ hash = {}
164
+ self.class.attribute_map.each_pair do |attr, param|
165
+ value = self.send(attr)
166
+ if value.nil?
167
+ is_nullable = self.class.openapi_nullable.include?(attr)
168
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
169
+ end
170
+
171
+ hash[param] = _to_hash(value)
172
+ end
173
+ hash
174
+ end
175
+
176
+ end
177
+
178
+ end
@@ -11,5 +11,5 @@ Generator version: 7.19.0
11
11
  =end
12
12
 
13
13
  module Late
14
- VERSION = '0.0.87'
14
+ VERSION = '0.0.89'
15
15
  end
data/lib/late-sdk.rb CHANGED
@@ -25,6 +25,7 @@ require 'late-sdk/models/accounts_list_response'
25
25
  require 'late-sdk/models/activate_sequence200_response'
26
26
  require 'late-sdk/models/add_broadcast_recipients200_response'
27
27
  require 'late-sdk/models/add_broadcast_recipients_request'
28
+ require 'late-sdk/models/add_message_reaction_request'
28
29
  require 'late-sdk/models/add_whats_app_broadcast_recipients200_response'
29
30
  require 'late-sdk/models/add_whats_app_broadcast_recipients_request'
30
31
  require 'late-sdk/models/add_whats_app_broadcast_recipients_request_recipients_inner'
@@ -537,6 +538,7 @@ require 'late-sdk/models/send_inbox_message_request_template_elements_inner'
537
538
  require 'late-sdk/models/send_inbox_message_request_template_elements_inner_buttons_inner'
538
539
  require 'late-sdk/models/send_private_reply_to_comment200_response'
539
540
  require 'late-sdk/models/send_private_reply_to_comment_request'
541
+ require 'late-sdk/models/send_typing_indicator_request'
540
542
  require 'late-sdk/models/send_whats_app_broadcast200_response'
541
543
  require 'late-sdk/models/send_whats_app_bulk200_response'
542
544
  require 'late-sdk/models/send_whats_app_bulk200_response_results_inner'
@@ -633,6 +635,7 @@ require 'late-sdk/models/update_whats_app_group_chat_request'
633
635
  require 'late-sdk/models/update_whats_app_template200_response'
634
636
  require 'late-sdk/models/update_whats_app_template200_response_template'
635
637
  require 'late-sdk/models/update_whats_app_template_request'
638
+ require 'late-sdk/models/upload_media_direct200_response'
636
639
  require 'late-sdk/models/upload_token_response'
637
640
  require 'late-sdk/models/upload_token_status_response'
638
641
  require 'late-sdk/models/uploaded_file'
data/openapi.yaml CHANGED
@@ -11072,6 +11072,8 @@ paths:
11072
11072
  description: |
11073
11073
  Fetch conversations (DMs) from all connected messaging accounts in a single API call. Supports filtering by profile and platform. Results are aggregated and deduplicated.
11074
11074
  Supported platforms: Facebook, Instagram, Twitter/X, Bluesky, Reddit, Telegram.
11075
+
11076
+ **Twitter/X limitation:** X has replaced traditional DMs with encrypted "X Chat" for many accounts. Messages sent or received through encrypted X Chat are not accessible via X's API (the `/2/dm_events` endpoint only returns legacy unencrypted DMs). This means some Twitter/X conversations may show only outgoing messages or appear empty. This is an X platform limitation that affects all third-party applications. See [X's docs on encrypted messaging](https://help.x.com/en/using-x/about-chat) for more details.
11075
11077
  tags: [Messages]
11076
11078
  security: [{ bearerAuth: [] }]
11077
11079
  parameters:
@@ -11316,7 +11318,10 @@ paths:
11316
11318
  get:
11317
11319
  operationId: getInboxConversationMessages
11318
11320
  summary: List messages
11319
- description: Fetch messages for a specific conversation. Requires accountId query parameter.
11321
+ description: |
11322
+ Fetch messages for a specific conversation. Requires accountId query parameter.
11323
+
11324
+ **Twitter/X limitation:** X's encrypted "X Chat" messages are not accessible via the API. Conversations where the other participant uses encrypted X Chat may only show your outgoing messages. See the [list conversations endpoint](#/Messages/listInboxConversations) for more details.
11320
11325
  tags: [Messages]
11321
11326
  security: [{ bearerAuth: [] }]
11322
11327
  parameters:
@@ -11605,6 +11610,230 @@ paths:
11605
11610
  '401': { $ref: '#/components/responses/Unauthorized' }
11606
11611
  '403':
11607
11612
  description: Inbox addon required
11613
+ delete:
11614
+ operationId: deleteInboxMessage
11615
+ summary: Delete message
11616
+ description: |
11617
+ Delete a message from a conversation. Platform support varies:
11618
+ - **Telegram**: Full delete (bot's own messages anytime, others if admin)
11619
+ - **X/Twitter**: Full delete (own DM events only)
11620
+ - **Bluesky**: Delete for self only (recipient still sees it)
11621
+ - **Reddit**: Delete from sender's view only
11622
+ - **Facebook, Instagram, WhatsApp**: Not supported (returns 400)
11623
+ tags: [Messages]
11624
+ security: [{ bearerAuth: [] }]
11625
+ parameters:
11626
+ - name: conversationId
11627
+ in: path
11628
+ required: true
11629
+ schema: { type: string }
11630
+ description: The conversation ID
11631
+ - name: messageId
11632
+ in: path
11633
+ required: true
11634
+ schema: { type: string }
11635
+ description: The platform message ID to delete
11636
+ - name: accountId
11637
+ in: query
11638
+ required: true
11639
+ schema: { type: string }
11640
+ description: Social account ID
11641
+ responses:
11642
+ '200':
11643
+ description: Message deleted
11644
+ content:
11645
+ application/json:
11646
+ schema:
11647
+ type: object
11648
+ properties:
11649
+ success: { type: boolean }
11650
+ '400':
11651
+ description: Platform does not support deletion or invalid request
11652
+ '401': { $ref: '#/components/responses/Unauthorized' }
11653
+ '403':
11654
+ description: Inbox addon required
11655
+ '404':
11656
+ description: Account or conversation not found
11657
+
11658
+ /v1/inbox/conversations/{conversationId}/typing:
11659
+ post:
11660
+ operationId: sendTypingIndicator
11661
+ summary: Send typing indicator
11662
+ description: |
11663
+ Show a typing indicator in a conversation. Platform support:
11664
+ - **Facebook Messenger**: Shows "Page is typing..." for 20 seconds
11665
+ - **Telegram**: Shows "Bot is typing..." for 5 seconds
11666
+ - **All others**: Returns 200 but no-op (platform doesn't support it)
11667
+
11668
+ Typing indicators are best-effort. The endpoint always returns 200 even if the platform call fails.
11669
+ tags: [Messages]
11670
+ security: [{ bearerAuth: [] }]
11671
+ parameters:
11672
+ - name: conversationId
11673
+ in: path
11674
+ required: true
11675
+ schema: { type: string }
11676
+ description: The conversation ID
11677
+ requestBody:
11678
+ required: true
11679
+ content:
11680
+ application/json:
11681
+ schema:
11682
+ type: object
11683
+ required: [accountId]
11684
+ properties:
11685
+ accountId: { type: string, description: Social account ID }
11686
+ responses:
11687
+ '200':
11688
+ description: Typing indicator sent (or no-op on unsupported platforms)
11689
+ content:
11690
+ application/json:
11691
+ schema:
11692
+ type: object
11693
+ properties:
11694
+ success: { type: boolean }
11695
+ '401': { $ref: '#/components/responses/Unauthorized' }
11696
+ '403':
11697
+ description: Inbox addon required
11698
+ '404':
11699
+ description: Account or conversation not found
11700
+
11701
+ /v1/inbox/conversations/{conversationId}/messages/{messageId}/reactions:
11702
+ post:
11703
+ operationId: addMessageReaction
11704
+ summary: Add reaction
11705
+ description: |
11706
+ Add an emoji reaction to a message. Platform support:
11707
+ - **Telegram**: Supports a subset of Unicode emoji reactions
11708
+ - **WhatsApp**: Supports any standard emoji (one reaction per message per sender)
11709
+ - **All others**: Returns 400 (not supported)
11710
+ tags: [Messages]
11711
+ security: [{ bearerAuth: [] }]
11712
+ parameters:
11713
+ - name: conversationId
11714
+ in: path
11715
+ required: true
11716
+ schema: { type: string }
11717
+ description: The conversation ID
11718
+ - name: messageId
11719
+ in: path
11720
+ required: true
11721
+ schema: { type: string }
11722
+ description: The platform message ID to react to
11723
+ requestBody:
11724
+ required: true
11725
+ content:
11726
+ application/json:
11727
+ schema:
11728
+ type: object
11729
+ required: [accountId, emoji]
11730
+ properties:
11731
+ accountId: { type: string, description: Social account ID }
11732
+ emoji: { type: string, description: 'Emoji character (e.g. "👍", "❤️")', example: '👍' }
11733
+ responses:
11734
+ '200':
11735
+ description: Reaction added
11736
+ content:
11737
+ application/json:
11738
+ schema:
11739
+ type: object
11740
+ properties:
11741
+ success: { type: boolean }
11742
+ '400':
11743
+ description: Platform does not support reactions or invalid request
11744
+ '401': { $ref: '#/components/responses/Unauthorized' }
11745
+ '403':
11746
+ description: Inbox addon required
11747
+ '404':
11748
+ description: Account or conversation not found
11749
+ delete:
11750
+ operationId: removeMessageReaction
11751
+ summary: Remove reaction
11752
+ description: |
11753
+ Remove a reaction from a message. Platform support:
11754
+ - **Telegram**: Send empty reaction array to clear
11755
+ - **WhatsApp**: Send empty emoji to remove
11756
+ - **All others**: Returns 400 (not supported)
11757
+ tags: [Messages]
11758
+ security: [{ bearerAuth: [] }]
11759
+ parameters:
11760
+ - name: conversationId
11761
+ in: path
11762
+ required: true
11763
+ schema: { type: string }
11764
+ description: The conversation ID
11765
+ - name: messageId
11766
+ in: path
11767
+ required: true
11768
+ schema: { type: string }
11769
+ description: The platform message ID
11770
+ - name: accountId
11771
+ in: query
11772
+ required: true
11773
+ schema: { type: string }
11774
+ description: Social account ID
11775
+ responses:
11776
+ '200':
11777
+ description: Reaction removed
11778
+ content:
11779
+ application/json:
11780
+ schema:
11781
+ type: object
11782
+ properties:
11783
+ success: { type: boolean }
11784
+ '400':
11785
+ description: Platform does not support reactions or invalid request
11786
+ '401': { $ref: '#/components/responses/Unauthorized' }
11787
+ '403':
11788
+ description: Inbox addon required
11789
+ '404':
11790
+ description: Account or conversation not found
11791
+
11792
+ /v1/media/upload-direct:
11793
+ post:
11794
+ operationId: uploadMediaDirect
11795
+ summary: Upload media file
11796
+ description: |
11797
+ Upload a media file using API key authentication and get back a publicly accessible URL.
11798
+ The URL can be used as `attachmentUrl` when sending inbox messages.
11799
+
11800
+ Files are stored in temporary storage and auto-delete after 7 days.
11801
+ Maximum file size is 25MB.
11802
+
11803
+ Unlike `/v1/media/upload` (which uses upload tokens for end-user flows),
11804
+ this endpoint uses standard Bearer token authentication for programmatic use.
11805
+ tags: [Messages]
11806
+ security: [{ bearerAuth: [] }]
11807
+ requestBody:
11808
+ required: true
11809
+ content:
11810
+ multipart/form-data:
11811
+ schema:
11812
+ type: object
11813
+ required: [file]
11814
+ properties:
11815
+ file:
11816
+ type: string
11817
+ format: binary
11818
+ description: The file to upload (max 25MB)
11819
+ contentType:
11820
+ type: string
11821
+ description: 'Override MIME type (e.g. "image/jpeg"). Auto-detected from file if not provided.'
11822
+ responses:
11823
+ '200':
11824
+ description: File uploaded successfully
11825
+ content:
11826
+ application/json:
11827
+ schema:
11828
+ type: object
11829
+ properties:
11830
+ url: { type: string, description: Publicly accessible URL for the uploaded file }
11831
+ filename: { type: string, description: Generated unique filename }
11832
+ contentType: { type: string, description: MIME type of the file }
11833
+ size: { type: integer, description: File size in bytes }
11834
+ '400':
11835
+ description: No file provided or file too large
11836
+ '401': { $ref: '#/components/responses/Unauthorized' }
11608
11837
 
11609
11838
  /v1/accounts/{accountId}/messenger-menu:
11610
11839
  get: