kapso-client-ruby 1.0.0 → 1.0.2
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/.rubocop.yml +81 -81
- data/CHANGELOG.md +262 -91
- data/Gemfile +20 -20
- data/RAILS_INTEGRATION.md +478 -0
- data/README.md +1053 -734
- data/Rakefile +40 -40
- data/TEMPLATE_TOOLS_GUIDE.md +120 -120
- data/WHATSAPP_24_HOUR_GUIDE.md +133 -133
- data/examples/advanced_features.rb +352 -349
- data/examples/advanced_messaging.rb +241 -0
- data/examples/basic_messaging.rb +139 -136
- data/examples/enhanced_interactive.rb +400 -0
- data/examples/flows_usage.rb +307 -0
- data/examples/interactive_messages.rb +343 -0
- data/examples/media_management.rb +256 -253
- data/examples/rails/jobs.rb +388 -0
- data/examples/rails/models.rb +240 -0
- data/examples/rails/notifications_controller.rb +227 -0
- data/examples/template_management.rb +393 -390
- data/kapso-ruby-logo.jpg +0 -0
- data/lib/kapso_client_ruby/client.rb +321 -316
- data/lib/kapso_client_ruby/errors.rb +348 -329
- data/lib/kapso_client_ruby/rails/generators/install_generator.rb +76 -0
- data/lib/kapso_client_ruby/rails/generators/templates/env.erb +21 -0
- data/lib/kapso_client_ruby/rails/generators/templates/initializer.rb.erb +33 -0
- data/lib/kapso_client_ruby/rails/generators/templates/message_service.rb.erb +138 -0
- data/lib/kapso_client_ruby/rails/generators/templates/webhook_controller.rb.erb +62 -0
- data/lib/kapso_client_ruby/rails/railtie.rb +55 -0
- data/lib/kapso_client_ruby/rails/service.rb +189 -0
- data/lib/kapso_client_ruby/rails/tasks.rake +167 -0
- data/lib/kapso_client_ruby/resources/calls.rb +172 -172
- data/lib/kapso_client_ruby/resources/contacts.rb +190 -190
- data/lib/kapso_client_ruby/resources/conversations.rb +103 -103
- data/lib/kapso_client_ruby/resources/flows.rb +382 -0
- data/lib/kapso_client_ruby/resources/media.rb +205 -205
- data/lib/kapso_client_ruby/resources/messages.rb +760 -380
- data/lib/kapso_client_ruby/resources/phone_numbers.rb +85 -85
- data/lib/kapso_client_ruby/resources/templates.rb +283 -283
- data/lib/kapso_client_ruby/types.rb +348 -262
- data/lib/kapso_client_ruby/version.rb +5 -5
- data/lib/kapso_client_ruby.rb +75 -68
- data/scripts/.env.example +17 -17
- data/scripts/kapso_template_finder.rb +91 -91
- data/scripts/sdk_setup.rb +404 -404
- data/scripts/test.rb +60 -60
- metadata +24 -3
|
@@ -1,191 +1,191 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module KapsoClientRuby
|
|
4
|
-
module Resources
|
|
5
|
-
class Contacts
|
|
6
|
-
def initialize(client)
|
|
7
|
-
@client = client
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
# List contacts (Kapso Proxy only)
|
|
11
|
-
def list(phone_number_id:, customer_id: nil, phone_number: nil,
|
|
12
|
-
profile_name: nil, limit: nil, after: nil, before: nil, fields: nil)
|
|
13
|
-
assert_kapso_proxy('Contacts API')
|
|
14
|
-
|
|
15
|
-
query_params = {
|
|
16
|
-
customer_id: customer_id,
|
|
17
|
-
phone_number: phone_number,
|
|
18
|
-
profile_name: profile_name,
|
|
19
|
-
limit: limit,
|
|
20
|
-
after: after,
|
|
21
|
-
before: before,
|
|
22
|
-
fields: fields
|
|
23
|
-
}.compact
|
|
24
|
-
|
|
25
|
-
response = @client.request(:get, "#{phone_number_id}/contacts",
|
|
26
|
-
query: query_params, response_type: :json)
|
|
27
|
-
Types::PagedResponse.new(response, Types::ContactRecord)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Get contact details (Kapso Proxy only)
|
|
31
|
-
def get(phone_number_id:, wa_id:, fields: nil)
|
|
32
|
-
assert_kapso_proxy('Contacts API')
|
|
33
|
-
|
|
34
|
-
raise ArgumentError, 'wa_id cannot be empty' if wa_id.nil? || wa_id.strip.empty?
|
|
35
|
-
|
|
36
|
-
query_params = {}
|
|
37
|
-
query_params[:fields] = fields if fields
|
|
38
|
-
|
|
39
|
-
response = @client.request(:get, "#{phone_number_id}/contacts/#{wa_id}",
|
|
40
|
-
query: query_params, response_type: :json)
|
|
41
|
-
|
|
42
|
-
# Handle both single object and data envelope responses
|
|
43
|
-
if response.is_a?(Hash) && response.key?('data')
|
|
44
|
-
Types::ContactRecord.new(response['data'])
|
|
45
|
-
else
|
|
46
|
-
Types::ContactRecord.new(response)
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# Update contact metadata (Kapso Proxy only)
|
|
51
|
-
def update(phone_number_id:, wa_id:, metadata: nil, tags: nil,
|
|
52
|
-
customer_id: nil, notes: nil)
|
|
53
|
-
assert_kapso_proxy('Contacts API')
|
|
54
|
-
|
|
55
|
-
raise ArgumentError, 'wa_id cannot be empty' if wa_id.nil? || wa_id.strip.empty?
|
|
56
|
-
|
|
57
|
-
payload = {}
|
|
58
|
-
payload[:metadata] = metadata if metadata
|
|
59
|
-
payload[:tags] = tags if tags
|
|
60
|
-
payload[:customer_id] = customer_id if customer_id
|
|
61
|
-
payload[:notes] = notes if notes
|
|
62
|
-
|
|
63
|
-
return if payload.empty?
|
|
64
|
-
|
|
65
|
-
response = @client.request(:patch, "#{phone_number_id}/contacts/#{wa_id}",
|
|
66
|
-
body: payload.to_json, response_type: :json)
|
|
67
|
-
Types::GraphSuccessResponse.new(response)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# Add tags to contact (Kapso Proxy only)
|
|
71
|
-
def add_tags(phone_number_id:, wa_id:, tags:)
|
|
72
|
-
raise ArgumentError, 'tags cannot be empty' if tags.nil? || tags.empty?
|
|
73
|
-
|
|
74
|
-
current_contact = get(phone_number_id: phone_number_id, wa_id: wa_id)
|
|
75
|
-
existing_tags = (current_contact.metadata&.[]('tags') || [])
|
|
76
|
-
new_tags = (existing_tags + Array(tags)).uniq
|
|
77
|
-
|
|
78
|
-
update(phone_number_id: phone_number_id, wa_id: wa_id,
|
|
79
|
-
metadata: { tags: new_tags })
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# Remove tags from contact (Kapso Proxy only)
|
|
83
|
-
def remove_tags(phone_number_id:, wa_id:, tags:)
|
|
84
|
-
raise ArgumentError, 'tags cannot be empty' if tags.nil? || tags.empty?
|
|
85
|
-
|
|
86
|
-
current_contact = get(phone_number_id: phone_number_id, wa_id: wa_id)
|
|
87
|
-
existing_tags = (current_contact.metadata&.[]('tags') || [])
|
|
88
|
-
remaining_tags = existing_tags - Array(tags)
|
|
89
|
-
|
|
90
|
-
update(phone_number_id: phone_number_id, wa_id: wa_id,
|
|
91
|
-
metadata: { tags: remaining_tags })
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
# Search contacts by various criteria (Kapso Proxy only)
|
|
95
|
-
def search(phone_number_id:, query:, search_in: ['profile_name', 'phone_number'],
|
|
96
|
-
limit: nil, after: nil, before: nil)
|
|
97
|
-
assert_kapso_proxy('Contacts Search API')
|
|
98
|
-
|
|
99
|
-
raise ArgumentError, 'query cannot be empty' if query.nil? || query.strip.empty?
|
|
100
|
-
|
|
101
|
-
query_params = {
|
|
102
|
-
q: query,
|
|
103
|
-
search_in: Array(search_in).join(','),
|
|
104
|
-
limit: limit,
|
|
105
|
-
after: after,
|
|
106
|
-
before: before
|
|
107
|
-
}.compact
|
|
108
|
-
|
|
109
|
-
response = @client.request(:get, "#{phone_number_id}/contacts/search",
|
|
110
|
-
query: query_params, response_type: :json)
|
|
111
|
-
Types::PagedResponse.new(response, Types::ContactRecord)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# Get contact analytics (Kapso Proxy only)
|
|
115
|
-
def analytics(phone_number_id:, wa_id: nil, since: nil, until_time: nil,
|
|
116
|
-
granularity: 'day', metrics: nil)
|
|
117
|
-
assert_kapso_proxy('Contact Analytics API')
|
|
118
|
-
|
|
119
|
-
query_params = {
|
|
120
|
-
wa_id: wa_id,
|
|
121
|
-
since: since,
|
|
122
|
-
until: until_time,
|
|
123
|
-
granularity: granularity
|
|
124
|
-
}
|
|
125
|
-
query_params[:metrics] = Array(metrics).join(',') if metrics
|
|
126
|
-
query_params = query_params.compact
|
|
127
|
-
|
|
128
|
-
response = @client.request(:get, "#{phone_number_id}/contacts/analytics",
|
|
129
|
-
query: query_params, response_type: :json)
|
|
130
|
-
response
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# Export contacts (Kapso Proxy only)
|
|
134
|
-
def export(phone_number_id:, format: 'csv', filters: nil)
|
|
135
|
-
assert_kapso_proxy('Contacts Export API')
|
|
136
|
-
|
|
137
|
-
payload = {
|
|
138
|
-
format: format,
|
|
139
|
-
filters: filters
|
|
140
|
-
}.compact
|
|
141
|
-
|
|
142
|
-
response = @client.request(:post, "#{phone_number_id}/contacts/export",
|
|
143
|
-
body: payload.to_json, response_type: :json)
|
|
144
|
-
response
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
# Import contacts (Kapso Proxy only)
|
|
148
|
-
def import(phone_number_id:, file:, format: 'csv', mapping: nil,
|
|
149
|
-
duplicate_handling: 'skip')
|
|
150
|
-
assert_kapso_proxy('Contacts Import API')
|
|
151
|
-
|
|
152
|
-
# Build multipart form data
|
|
153
|
-
form_data = {
|
|
154
|
-
'format' => format,
|
|
155
|
-
'duplicate_handling' => duplicate_handling
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
# Handle file parameter
|
|
159
|
-
file_obj = case file
|
|
160
|
-
when String
|
|
161
|
-
File.open(file, 'rb')
|
|
162
|
-
when File, IO, StringIO
|
|
163
|
-
file
|
|
164
|
-
else
|
|
165
|
-
raise ArgumentError, 'file must be a File, IO object, or file path string'
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
form_data['file'] = Faraday::UploadIO.new(file_obj, 'text/csv', 'contacts.csv')
|
|
169
|
-
form_data['mapping'] = mapping.to_json if mapping
|
|
170
|
-
|
|
171
|
-
headers = { 'Content-Type' => 'multipart/form-data' }
|
|
172
|
-
|
|
173
|
-
response = @client.request(:post, "#{phone_number_id}/contacts/import",
|
|
174
|
-
body: form_data, headers: headers, response_type: :json)
|
|
175
|
-
|
|
176
|
-
# Close file if we opened it
|
|
177
|
-
file_obj.close if file.is_a?(String) && file_obj.respond_to?(:close)
|
|
178
|
-
|
|
179
|
-
response
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
private
|
|
183
|
-
|
|
184
|
-
def assert_kapso_proxy(feature)
|
|
185
|
-
unless @client.kapso_proxy?
|
|
186
|
-
raise Errors::KapsoProxyRequiredError.new(feature)
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
end
|
|
190
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KapsoClientRuby
|
|
4
|
+
module Resources
|
|
5
|
+
class Contacts
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# List contacts (Kapso Proxy only)
|
|
11
|
+
def list(phone_number_id:, customer_id: nil, phone_number: nil,
|
|
12
|
+
profile_name: nil, limit: nil, after: nil, before: nil, fields: nil)
|
|
13
|
+
assert_kapso_proxy('Contacts API')
|
|
14
|
+
|
|
15
|
+
query_params = {
|
|
16
|
+
customer_id: customer_id,
|
|
17
|
+
phone_number: phone_number,
|
|
18
|
+
profile_name: profile_name,
|
|
19
|
+
limit: limit,
|
|
20
|
+
after: after,
|
|
21
|
+
before: before,
|
|
22
|
+
fields: fields
|
|
23
|
+
}.compact
|
|
24
|
+
|
|
25
|
+
response = @client.request(:get, "#{phone_number_id}/contacts",
|
|
26
|
+
query: query_params, response_type: :json)
|
|
27
|
+
Types::PagedResponse.new(response, Types::ContactRecord)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Get contact details (Kapso Proxy only)
|
|
31
|
+
def get(phone_number_id:, wa_id:, fields: nil)
|
|
32
|
+
assert_kapso_proxy('Contacts API')
|
|
33
|
+
|
|
34
|
+
raise ArgumentError, 'wa_id cannot be empty' if wa_id.nil? || wa_id.strip.empty?
|
|
35
|
+
|
|
36
|
+
query_params = {}
|
|
37
|
+
query_params[:fields] = fields if fields
|
|
38
|
+
|
|
39
|
+
response = @client.request(:get, "#{phone_number_id}/contacts/#{wa_id}",
|
|
40
|
+
query: query_params, response_type: :json)
|
|
41
|
+
|
|
42
|
+
# Handle both single object and data envelope responses
|
|
43
|
+
if response.is_a?(Hash) && response.key?('data')
|
|
44
|
+
Types::ContactRecord.new(response['data'])
|
|
45
|
+
else
|
|
46
|
+
Types::ContactRecord.new(response)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Update contact metadata (Kapso Proxy only)
|
|
51
|
+
def update(phone_number_id:, wa_id:, metadata: nil, tags: nil,
|
|
52
|
+
customer_id: nil, notes: nil)
|
|
53
|
+
assert_kapso_proxy('Contacts API')
|
|
54
|
+
|
|
55
|
+
raise ArgumentError, 'wa_id cannot be empty' if wa_id.nil? || wa_id.strip.empty?
|
|
56
|
+
|
|
57
|
+
payload = {}
|
|
58
|
+
payload[:metadata] = metadata if metadata
|
|
59
|
+
payload[:tags] = tags if tags
|
|
60
|
+
payload[:customer_id] = customer_id if customer_id
|
|
61
|
+
payload[:notes] = notes if notes
|
|
62
|
+
|
|
63
|
+
return if payload.empty?
|
|
64
|
+
|
|
65
|
+
response = @client.request(:patch, "#{phone_number_id}/contacts/#{wa_id}",
|
|
66
|
+
body: payload.to_json, response_type: :json)
|
|
67
|
+
Types::GraphSuccessResponse.new(response)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Add tags to contact (Kapso Proxy only)
|
|
71
|
+
def add_tags(phone_number_id:, wa_id:, tags:)
|
|
72
|
+
raise ArgumentError, 'tags cannot be empty' if tags.nil? || tags.empty?
|
|
73
|
+
|
|
74
|
+
current_contact = get(phone_number_id: phone_number_id, wa_id: wa_id)
|
|
75
|
+
existing_tags = (current_contact.metadata&.[]('tags') || [])
|
|
76
|
+
new_tags = (existing_tags + Array(tags)).uniq
|
|
77
|
+
|
|
78
|
+
update(phone_number_id: phone_number_id, wa_id: wa_id,
|
|
79
|
+
metadata: { tags: new_tags })
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Remove tags from contact (Kapso Proxy only)
|
|
83
|
+
def remove_tags(phone_number_id:, wa_id:, tags:)
|
|
84
|
+
raise ArgumentError, 'tags cannot be empty' if tags.nil? || tags.empty?
|
|
85
|
+
|
|
86
|
+
current_contact = get(phone_number_id: phone_number_id, wa_id: wa_id)
|
|
87
|
+
existing_tags = (current_contact.metadata&.[]('tags') || [])
|
|
88
|
+
remaining_tags = existing_tags - Array(tags)
|
|
89
|
+
|
|
90
|
+
update(phone_number_id: phone_number_id, wa_id: wa_id,
|
|
91
|
+
metadata: { tags: remaining_tags })
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Search contacts by various criteria (Kapso Proxy only)
|
|
95
|
+
def search(phone_number_id:, query:, search_in: ['profile_name', 'phone_number'],
|
|
96
|
+
limit: nil, after: nil, before: nil)
|
|
97
|
+
assert_kapso_proxy('Contacts Search API')
|
|
98
|
+
|
|
99
|
+
raise ArgumentError, 'query cannot be empty' if query.nil? || query.strip.empty?
|
|
100
|
+
|
|
101
|
+
query_params = {
|
|
102
|
+
q: query,
|
|
103
|
+
search_in: Array(search_in).join(','),
|
|
104
|
+
limit: limit,
|
|
105
|
+
after: after,
|
|
106
|
+
before: before
|
|
107
|
+
}.compact
|
|
108
|
+
|
|
109
|
+
response = @client.request(:get, "#{phone_number_id}/contacts/search",
|
|
110
|
+
query: query_params, response_type: :json)
|
|
111
|
+
Types::PagedResponse.new(response, Types::ContactRecord)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Get contact analytics (Kapso Proxy only)
|
|
115
|
+
def analytics(phone_number_id:, wa_id: nil, since: nil, until_time: nil,
|
|
116
|
+
granularity: 'day', metrics: nil)
|
|
117
|
+
assert_kapso_proxy('Contact Analytics API')
|
|
118
|
+
|
|
119
|
+
query_params = {
|
|
120
|
+
wa_id: wa_id,
|
|
121
|
+
since: since,
|
|
122
|
+
until: until_time,
|
|
123
|
+
granularity: granularity
|
|
124
|
+
}
|
|
125
|
+
query_params[:metrics] = Array(metrics).join(',') if metrics
|
|
126
|
+
query_params = query_params.compact
|
|
127
|
+
|
|
128
|
+
response = @client.request(:get, "#{phone_number_id}/contacts/analytics",
|
|
129
|
+
query: query_params, response_type: :json)
|
|
130
|
+
response
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Export contacts (Kapso Proxy only)
|
|
134
|
+
def export(phone_number_id:, format: 'csv', filters: nil)
|
|
135
|
+
assert_kapso_proxy('Contacts Export API')
|
|
136
|
+
|
|
137
|
+
payload = {
|
|
138
|
+
format: format,
|
|
139
|
+
filters: filters
|
|
140
|
+
}.compact
|
|
141
|
+
|
|
142
|
+
response = @client.request(:post, "#{phone_number_id}/contacts/export",
|
|
143
|
+
body: payload.to_json, response_type: :json)
|
|
144
|
+
response
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Import contacts (Kapso Proxy only)
|
|
148
|
+
def import(phone_number_id:, file:, format: 'csv', mapping: nil,
|
|
149
|
+
duplicate_handling: 'skip')
|
|
150
|
+
assert_kapso_proxy('Contacts Import API')
|
|
151
|
+
|
|
152
|
+
# Build multipart form data
|
|
153
|
+
form_data = {
|
|
154
|
+
'format' => format,
|
|
155
|
+
'duplicate_handling' => duplicate_handling
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
# Handle file parameter
|
|
159
|
+
file_obj = case file
|
|
160
|
+
when String
|
|
161
|
+
File.open(file, 'rb')
|
|
162
|
+
when File, IO, StringIO
|
|
163
|
+
file
|
|
164
|
+
else
|
|
165
|
+
raise ArgumentError, 'file must be a File, IO object, or file path string'
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
form_data['file'] = Faraday::UploadIO.new(file_obj, 'text/csv', 'contacts.csv')
|
|
169
|
+
form_data['mapping'] = mapping.to_json if mapping
|
|
170
|
+
|
|
171
|
+
headers = { 'Content-Type' => 'multipart/form-data' }
|
|
172
|
+
|
|
173
|
+
response = @client.request(:post, "#{phone_number_id}/contacts/import",
|
|
174
|
+
body: form_data, headers: headers, response_type: :json)
|
|
175
|
+
|
|
176
|
+
# Close file if we opened it
|
|
177
|
+
file_obj.close if file.is_a?(String) && file_obj.respond_to?(:close)
|
|
178
|
+
|
|
179
|
+
response
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
private
|
|
183
|
+
|
|
184
|
+
def assert_kapso_proxy(feature)
|
|
185
|
+
unless @client.kapso_proxy?
|
|
186
|
+
raise Errors::KapsoProxyRequiredError.new(feature)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
191
|
end
|
|
@@ -1,104 +1,104 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module KapsoClientRuby
|
|
4
|
-
module Resources
|
|
5
|
-
class Conversations
|
|
6
|
-
def initialize(client)
|
|
7
|
-
@client = client
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
# List conversations (Kapso Proxy only)
|
|
11
|
-
def list(phone_number_id:, status: nil, last_active_since: nil,
|
|
12
|
-
last_active_until: nil, phone_number: nil, limit: nil,
|
|
13
|
-
after: nil, before: nil, fields: nil)
|
|
14
|
-
assert_kapso_proxy('Conversations API')
|
|
15
|
-
|
|
16
|
-
query_params = {
|
|
17
|
-
status: status,
|
|
18
|
-
last_active_since: last_active_since,
|
|
19
|
-
last_active_until: last_active_until,
|
|
20
|
-
phone_number: phone_number,
|
|
21
|
-
limit: limit,
|
|
22
|
-
after: after,
|
|
23
|
-
before: before,
|
|
24
|
-
fields: fields
|
|
25
|
-
}.compact
|
|
26
|
-
|
|
27
|
-
response = @client.request(:get, "#{phone_number_id}/conversations",
|
|
28
|
-
query: query_params, response_type: :json)
|
|
29
|
-
Types::PagedResponse.new(response, Types::ConversationRecord)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# Get conversation details (Kapso Proxy only)
|
|
33
|
-
def get(conversation_id:)
|
|
34
|
-
assert_kapso_proxy('Conversations API')
|
|
35
|
-
|
|
36
|
-
raise ArgumentError, 'conversation_id cannot be empty' if conversation_id.nil? || conversation_id.strip.empty?
|
|
37
|
-
|
|
38
|
-
response = @client.request(:get, "conversations/#{conversation_id}",
|
|
39
|
-
response_type: :json)
|
|
40
|
-
|
|
41
|
-
# Handle both single object and data envelope responses
|
|
42
|
-
if response.is_a?(Hash) && response.key?('data')
|
|
43
|
-
Types::ConversationRecord.new(response['data'])
|
|
44
|
-
else
|
|
45
|
-
Types::ConversationRecord.new(response)
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# Update conversation status (Kapso Proxy only)
|
|
50
|
-
def update_status(conversation_id:, status:)
|
|
51
|
-
assert_kapso_proxy('Conversations API')
|
|
52
|
-
|
|
53
|
-
raise ArgumentError, 'conversation_id cannot be empty' if conversation_id.nil? || conversation_id.strip.empty?
|
|
54
|
-
raise ArgumentError, 'status cannot be empty' if status.nil? || status.strip.empty?
|
|
55
|
-
|
|
56
|
-
payload = { status: status }
|
|
57
|
-
|
|
58
|
-
response = @client.request(:patch, "conversations/#{conversation_id}",
|
|
59
|
-
body: payload.to_json, response_type: :json)
|
|
60
|
-
Types::GraphSuccessResponse.new(response)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Archive conversation (Kapso Proxy only)
|
|
64
|
-
def archive(conversation_id:)
|
|
65
|
-
update_status(conversation_id: conversation_id, status: 'archived')
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Unarchive conversation (Kapso Proxy only)
|
|
69
|
-
def unarchive(conversation_id:)
|
|
70
|
-
update_status(conversation_id: conversation_id, status: 'active')
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# End conversation (Kapso Proxy only)
|
|
74
|
-
def end_conversation(conversation_id:)
|
|
75
|
-
update_status(conversation_id: conversation_id, status: 'ended')
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
# Get conversation analytics (Kapso Proxy only)
|
|
79
|
-
def analytics(phone_number_id:, conversation_id: nil, since: nil,
|
|
80
|
-
until_time: nil, granularity: 'day')
|
|
81
|
-
assert_kapso_proxy('Conversation Analytics API')
|
|
82
|
-
|
|
83
|
-
query_params = {
|
|
84
|
-
conversation_id: conversation_id,
|
|
85
|
-
since: since,
|
|
86
|
-
until: until_time,
|
|
87
|
-
granularity: granularity
|
|
88
|
-
}.compact
|
|
89
|
-
|
|
90
|
-
response = @client.request(:get, "#{phone_number_id}/conversations/analytics",
|
|
91
|
-
query: query_params, response_type: :json)
|
|
92
|
-
response
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
private
|
|
96
|
-
|
|
97
|
-
def assert_kapso_proxy(feature)
|
|
98
|
-
unless @client.kapso_proxy?
|
|
99
|
-
raise Errors::KapsoProxyRequiredError.new(feature)
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KapsoClientRuby
|
|
4
|
+
module Resources
|
|
5
|
+
class Conversations
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# List conversations (Kapso Proxy only)
|
|
11
|
+
def list(phone_number_id:, status: nil, last_active_since: nil,
|
|
12
|
+
last_active_until: nil, phone_number: nil, limit: nil,
|
|
13
|
+
after: nil, before: nil, fields: nil)
|
|
14
|
+
assert_kapso_proxy('Conversations API')
|
|
15
|
+
|
|
16
|
+
query_params = {
|
|
17
|
+
status: status,
|
|
18
|
+
last_active_since: last_active_since,
|
|
19
|
+
last_active_until: last_active_until,
|
|
20
|
+
phone_number: phone_number,
|
|
21
|
+
limit: limit,
|
|
22
|
+
after: after,
|
|
23
|
+
before: before,
|
|
24
|
+
fields: fields
|
|
25
|
+
}.compact
|
|
26
|
+
|
|
27
|
+
response = @client.request(:get, "#{phone_number_id}/conversations",
|
|
28
|
+
query: query_params, response_type: :json)
|
|
29
|
+
Types::PagedResponse.new(response, Types::ConversationRecord)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Get conversation details (Kapso Proxy only)
|
|
33
|
+
def get(conversation_id:)
|
|
34
|
+
assert_kapso_proxy('Conversations API')
|
|
35
|
+
|
|
36
|
+
raise ArgumentError, 'conversation_id cannot be empty' if conversation_id.nil? || conversation_id.strip.empty?
|
|
37
|
+
|
|
38
|
+
response = @client.request(:get, "conversations/#{conversation_id}",
|
|
39
|
+
response_type: :json)
|
|
40
|
+
|
|
41
|
+
# Handle both single object and data envelope responses
|
|
42
|
+
if response.is_a?(Hash) && response.key?('data')
|
|
43
|
+
Types::ConversationRecord.new(response['data'])
|
|
44
|
+
else
|
|
45
|
+
Types::ConversationRecord.new(response)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Update conversation status (Kapso Proxy only)
|
|
50
|
+
def update_status(conversation_id:, status:)
|
|
51
|
+
assert_kapso_proxy('Conversations API')
|
|
52
|
+
|
|
53
|
+
raise ArgumentError, 'conversation_id cannot be empty' if conversation_id.nil? || conversation_id.strip.empty?
|
|
54
|
+
raise ArgumentError, 'status cannot be empty' if status.nil? || status.strip.empty?
|
|
55
|
+
|
|
56
|
+
payload = { status: status }
|
|
57
|
+
|
|
58
|
+
response = @client.request(:patch, "conversations/#{conversation_id}",
|
|
59
|
+
body: payload.to_json, response_type: :json)
|
|
60
|
+
Types::GraphSuccessResponse.new(response)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Archive conversation (Kapso Proxy only)
|
|
64
|
+
def archive(conversation_id:)
|
|
65
|
+
update_status(conversation_id: conversation_id, status: 'archived')
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Unarchive conversation (Kapso Proxy only)
|
|
69
|
+
def unarchive(conversation_id:)
|
|
70
|
+
update_status(conversation_id: conversation_id, status: 'active')
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# End conversation (Kapso Proxy only)
|
|
74
|
+
def end_conversation(conversation_id:)
|
|
75
|
+
update_status(conversation_id: conversation_id, status: 'ended')
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Get conversation analytics (Kapso Proxy only)
|
|
79
|
+
def analytics(phone_number_id:, conversation_id: nil, since: nil,
|
|
80
|
+
until_time: nil, granularity: 'day')
|
|
81
|
+
assert_kapso_proxy('Conversation Analytics API')
|
|
82
|
+
|
|
83
|
+
query_params = {
|
|
84
|
+
conversation_id: conversation_id,
|
|
85
|
+
since: since,
|
|
86
|
+
until: until_time,
|
|
87
|
+
granularity: granularity
|
|
88
|
+
}.compact
|
|
89
|
+
|
|
90
|
+
response = @client.request(:get, "#{phone_number_id}/conversations/analytics",
|
|
91
|
+
query: query_params, response_type: :json)
|
|
92
|
+
response
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
private
|
|
96
|
+
|
|
97
|
+
def assert_kapso_proxy(feature)
|
|
98
|
+
unless @client.kapso_proxy?
|
|
99
|
+
raise Errors::KapsoProxyRequiredError.new(feature)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
104
|
end
|