kapso-client-ruby 1.0.1 → 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 +477 -477
- data/README.md +1053 -752
- 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 +387 -387
- data/examples/rails/models.rb +239 -239
- data/examples/rails/notifications_controller.rb +226 -226
- 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 +75 -75
- data/lib/kapso_client_ruby/rails/generators/templates/env.erb +20 -20
- data/lib/kapso_client_ruby/rails/generators/templates/initializer.rb.erb +32 -32
- data/lib/kapso_client_ruby/rails/generators/templates/message_service.rb.erb +137 -137
- data/lib/kapso_client_ruby/rails/generators/templates/webhook_controller.rb.erb +61 -61
- data/lib/kapso_client_ruby/rails/railtie.rb +54 -54
- data/lib/kapso_client_ruby/rails/service.rb +188 -188
- data/lib/kapso_client_ruby/rails/tasks.rake +166 -166
- 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 -74
- 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 +12 -3
|
@@ -1,227 +1,227 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Example Rails controller showing various WhatsApp integration patterns
|
|
4
|
-
class NotificationsController < ApplicationController
|
|
5
|
-
before_action :authenticate_user!
|
|
6
|
-
before_action :ensure_phone_number, only: [:send_notification, :send_order_update]
|
|
7
|
-
|
|
8
|
-
# GET /notifications
|
|
9
|
-
# Show notification preferences and send test message
|
|
10
|
-
def index
|
|
11
|
-
@user = current_user
|
|
12
|
-
@message_service = KapsoMessageService.new
|
|
13
|
-
@templates = @message_service.list_templates&.dig('data') || []
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# POST /notifications/test
|
|
17
|
-
# Send a test message to the current user
|
|
18
|
-
def send_test
|
|
19
|
-
service = KapsoMessageService.new
|
|
20
|
-
|
|
21
|
-
begin
|
|
22
|
-
result = service.send_text(
|
|
23
|
-
phone_number: current_user.phone_number,
|
|
24
|
-
message: "Hello #{current_user.name}! This is a test message from #{Rails.application.class.name.deconstantize}."
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
if result
|
|
28
|
-
flash[:success] = "Test message sent successfully! Message ID: #{result.dig('messages', 0, 'id')}"
|
|
29
|
-
else
|
|
30
|
-
flash[:error] = "Failed to send test message. Please check the logs."
|
|
31
|
-
end
|
|
32
|
-
rescue KapsoClientRuby::Error => e
|
|
33
|
-
flash[:error] = "Error sending message: #{e.message}"
|
|
34
|
-
Rails.logger.error "WhatsApp test message error: #{e.message}"
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
redirect_to notifications_path
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# POST /notifications/welcome
|
|
41
|
-
# Send welcome message using template
|
|
42
|
-
def send_welcome
|
|
43
|
-
service = KapsoMessageService.new
|
|
44
|
-
|
|
45
|
-
begin
|
|
46
|
-
result = service.send_welcome_message(current_user)
|
|
47
|
-
|
|
48
|
-
if result
|
|
49
|
-
flash[:success] = "Welcome message sent!"
|
|
50
|
-
|
|
51
|
-
# Track the sent message
|
|
52
|
-
current_user.whatsapp_messages.create!(
|
|
53
|
-
message_id: result.dig('messages', 0, 'id'),
|
|
54
|
-
message_type: 'welcome',
|
|
55
|
-
status: 'sent',
|
|
56
|
-
sent_at: Time.current
|
|
57
|
-
)
|
|
58
|
-
else
|
|
59
|
-
flash[:error] = "Failed to send welcome message."
|
|
60
|
-
end
|
|
61
|
-
rescue KapsoClientRuby::Error => e
|
|
62
|
-
flash[:error] = "Error: #{e.message}"
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
redirect_to notifications_path
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# POST /notifications/custom
|
|
69
|
-
# Send custom message with template
|
|
70
|
-
def send_custom
|
|
71
|
-
template_name = params[:template_name]
|
|
72
|
-
custom_params = params[:template_params] || {}
|
|
73
|
-
|
|
74
|
-
unless template_name.present?
|
|
75
|
-
flash[:error] = "Please select a template"
|
|
76
|
-
redirect_to notifications_path
|
|
77
|
-
return
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
service = KapsoClientRuby::Rails::Service.new
|
|
81
|
-
|
|
82
|
-
begin
|
|
83
|
-
# Build template components from form params
|
|
84
|
-
components = []
|
|
85
|
-
|
|
86
|
-
if custom_params.present?
|
|
87
|
-
body_params = custom_params.values.map do |param|
|
|
88
|
-
{ type: 'text', text: param.to_s }
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
components << {
|
|
92
|
-
type: 'body',
|
|
93
|
-
parameters: body_params
|
|
94
|
-
} if body_params.any?
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
result = service.send_template_message(
|
|
98
|
-
to: current_user.phone_number,
|
|
99
|
-
template_name: template_name,
|
|
100
|
-
language: current_user.preferred_language || 'en',
|
|
101
|
-
components: components
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
flash[:success] = "Template message sent! ID: #{result.dig('messages', 0, 'id')}"
|
|
105
|
-
|
|
106
|
-
# Log the message
|
|
107
|
-
Rails.logger.info "Template '#{template_name}' sent to #{current_user.phone_number}"
|
|
108
|
-
|
|
109
|
-
rescue KapsoClientRuby::Error => e
|
|
110
|
-
flash[:error] = "Failed to send template: #{e.message}"
|
|
111
|
-
Rails.logger.error "Template send error: #{e.message}"
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
redirect_to notifications_path
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# POST /notifications/document
|
|
118
|
-
# Send a document to the user
|
|
119
|
-
def send_document
|
|
120
|
-
document_url = params[:document_url]
|
|
121
|
-
filename = params[:filename]
|
|
122
|
-
caption = params[:caption]
|
|
123
|
-
|
|
124
|
-
unless document_url.present?
|
|
125
|
-
flash[:error] = "Document URL is required"
|
|
126
|
-
redirect_to notifications_path
|
|
127
|
-
return
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
service = KapsoMessageService.new
|
|
131
|
-
|
|
132
|
-
begin
|
|
133
|
-
result = service.send_document(
|
|
134
|
-
phone_number: current_user.phone_number,
|
|
135
|
-
document_url: document_url,
|
|
136
|
-
filename: filename,
|
|
137
|
-
caption: caption
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
flash[:success] = "Document sent successfully!"
|
|
141
|
-
Rails.logger.info "Document sent to #{current_user.phone_number}: #{document_url}"
|
|
142
|
-
|
|
143
|
-
rescue KapsoClientRuby::Error => e
|
|
144
|
-
flash[:error] = "Failed to send document: #{e.message}"
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
redirect_to notifications_path
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
# GET /notifications/message_status/:message_id
|
|
151
|
-
# Check status of a sent message
|
|
152
|
-
def message_status
|
|
153
|
-
message_id = params[:id]
|
|
154
|
-
service = KapsoMessageService.new
|
|
155
|
-
|
|
156
|
-
begin
|
|
157
|
-
status = service.get_message_status(message_id)
|
|
158
|
-
|
|
159
|
-
if status
|
|
160
|
-
render json: {
|
|
161
|
-
message_id: status['id'],
|
|
162
|
-
status: status['status'],
|
|
163
|
-
timestamp: status['timestamp'],
|
|
164
|
-
recipient_id: status['recipient_id']
|
|
165
|
-
}
|
|
166
|
-
else
|
|
167
|
-
render json: { error: 'Message not found' }, status: :not_found
|
|
168
|
-
end
|
|
169
|
-
rescue KapsoClientRuby::Error => e
|
|
170
|
-
render json: { error: e.message }, status: :unprocessable_entity
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
# POST /notifications/bulk
|
|
175
|
-
# Send bulk messages (should be queued in production)
|
|
176
|
-
def send_bulk
|
|
177
|
-
recipients = params[:recipients]&.split(',')&.map(&:strip) || []
|
|
178
|
-
message = params[:message]
|
|
179
|
-
|
|
180
|
-
if recipients.empty? || message.blank?
|
|
181
|
-
flash[:error] = "Recipients and message are required"
|
|
182
|
-
redirect_to notifications_path
|
|
183
|
-
return
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
# In production, this should be done via background jobs
|
|
187
|
-
successful_sends = 0
|
|
188
|
-
failed_sends = 0
|
|
189
|
-
|
|
190
|
-
recipients.each do |phone_number|
|
|
191
|
-
begin
|
|
192
|
-
service = KapsoMessageService.new
|
|
193
|
-
result = service.send_text(phone_number: phone_number, message: message)
|
|
194
|
-
|
|
195
|
-
if result
|
|
196
|
-
successful_sends += 1
|
|
197
|
-
Rails.logger.info "Bulk message sent to #{phone_number}"
|
|
198
|
-
else
|
|
199
|
-
failed_sends += 1
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
# Rate limiting - small delay between messages
|
|
203
|
-
sleep(0.5)
|
|
204
|
-
|
|
205
|
-
rescue KapsoClientRuby::Error => e
|
|
206
|
-
failed_sends += 1
|
|
207
|
-
Rails.logger.error "Bulk message failed for #{phone_number}: #{e.message}"
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
flash[:success] = "Bulk send complete: #{successful_sends} sent, #{failed_sends} failed"
|
|
212
|
-
redirect_to notifications_path
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
private
|
|
216
|
-
|
|
217
|
-
def ensure_phone_number
|
|
218
|
-
unless current_user.phone_number.present?
|
|
219
|
-
flash[:error] = "Please add a phone number to your profile first"
|
|
220
|
-
redirect_to edit_user_registration_path
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
def notification_params
|
|
225
|
-
params.permit(:message, :template_name, :document_url, :filename, :caption, :recipients, template_params: {})
|
|
226
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Example Rails controller showing various WhatsApp integration patterns
|
|
4
|
+
class NotificationsController < ApplicationController
|
|
5
|
+
before_action :authenticate_user!
|
|
6
|
+
before_action :ensure_phone_number, only: [:send_notification, :send_order_update]
|
|
7
|
+
|
|
8
|
+
# GET /notifications
|
|
9
|
+
# Show notification preferences and send test message
|
|
10
|
+
def index
|
|
11
|
+
@user = current_user
|
|
12
|
+
@message_service = KapsoMessageService.new
|
|
13
|
+
@templates = @message_service.list_templates&.dig('data') || []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# POST /notifications/test
|
|
17
|
+
# Send a test message to the current user
|
|
18
|
+
def send_test
|
|
19
|
+
service = KapsoMessageService.new
|
|
20
|
+
|
|
21
|
+
begin
|
|
22
|
+
result = service.send_text(
|
|
23
|
+
phone_number: current_user.phone_number,
|
|
24
|
+
message: "Hello #{current_user.name}! This is a test message from #{Rails.application.class.name.deconstantize}."
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
if result
|
|
28
|
+
flash[:success] = "Test message sent successfully! Message ID: #{result.dig('messages', 0, 'id')}"
|
|
29
|
+
else
|
|
30
|
+
flash[:error] = "Failed to send test message. Please check the logs."
|
|
31
|
+
end
|
|
32
|
+
rescue KapsoClientRuby::Error => e
|
|
33
|
+
flash[:error] = "Error sending message: #{e.message}"
|
|
34
|
+
Rails.logger.error "WhatsApp test message error: #{e.message}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
redirect_to notifications_path
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# POST /notifications/welcome
|
|
41
|
+
# Send welcome message using template
|
|
42
|
+
def send_welcome
|
|
43
|
+
service = KapsoMessageService.new
|
|
44
|
+
|
|
45
|
+
begin
|
|
46
|
+
result = service.send_welcome_message(current_user)
|
|
47
|
+
|
|
48
|
+
if result
|
|
49
|
+
flash[:success] = "Welcome message sent!"
|
|
50
|
+
|
|
51
|
+
# Track the sent message
|
|
52
|
+
current_user.whatsapp_messages.create!(
|
|
53
|
+
message_id: result.dig('messages', 0, 'id'),
|
|
54
|
+
message_type: 'welcome',
|
|
55
|
+
status: 'sent',
|
|
56
|
+
sent_at: Time.current
|
|
57
|
+
)
|
|
58
|
+
else
|
|
59
|
+
flash[:error] = "Failed to send welcome message."
|
|
60
|
+
end
|
|
61
|
+
rescue KapsoClientRuby::Error => e
|
|
62
|
+
flash[:error] = "Error: #{e.message}"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
redirect_to notifications_path
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# POST /notifications/custom
|
|
69
|
+
# Send custom message with template
|
|
70
|
+
def send_custom
|
|
71
|
+
template_name = params[:template_name]
|
|
72
|
+
custom_params = params[:template_params] || {}
|
|
73
|
+
|
|
74
|
+
unless template_name.present?
|
|
75
|
+
flash[:error] = "Please select a template"
|
|
76
|
+
redirect_to notifications_path
|
|
77
|
+
return
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
service = KapsoClientRuby::Rails::Service.new
|
|
81
|
+
|
|
82
|
+
begin
|
|
83
|
+
# Build template components from form params
|
|
84
|
+
components = []
|
|
85
|
+
|
|
86
|
+
if custom_params.present?
|
|
87
|
+
body_params = custom_params.values.map do |param|
|
|
88
|
+
{ type: 'text', text: param.to_s }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
components << {
|
|
92
|
+
type: 'body',
|
|
93
|
+
parameters: body_params
|
|
94
|
+
} if body_params.any?
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
result = service.send_template_message(
|
|
98
|
+
to: current_user.phone_number,
|
|
99
|
+
template_name: template_name,
|
|
100
|
+
language: current_user.preferred_language || 'en',
|
|
101
|
+
components: components
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
flash[:success] = "Template message sent! ID: #{result.dig('messages', 0, 'id')}"
|
|
105
|
+
|
|
106
|
+
# Log the message
|
|
107
|
+
Rails.logger.info "Template '#{template_name}' sent to #{current_user.phone_number}"
|
|
108
|
+
|
|
109
|
+
rescue KapsoClientRuby::Error => e
|
|
110
|
+
flash[:error] = "Failed to send template: #{e.message}"
|
|
111
|
+
Rails.logger.error "Template send error: #{e.message}"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
redirect_to notifications_path
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# POST /notifications/document
|
|
118
|
+
# Send a document to the user
|
|
119
|
+
def send_document
|
|
120
|
+
document_url = params[:document_url]
|
|
121
|
+
filename = params[:filename]
|
|
122
|
+
caption = params[:caption]
|
|
123
|
+
|
|
124
|
+
unless document_url.present?
|
|
125
|
+
flash[:error] = "Document URL is required"
|
|
126
|
+
redirect_to notifications_path
|
|
127
|
+
return
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
service = KapsoMessageService.new
|
|
131
|
+
|
|
132
|
+
begin
|
|
133
|
+
result = service.send_document(
|
|
134
|
+
phone_number: current_user.phone_number,
|
|
135
|
+
document_url: document_url,
|
|
136
|
+
filename: filename,
|
|
137
|
+
caption: caption
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
flash[:success] = "Document sent successfully!"
|
|
141
|
+
Rails.logger.info "Document sent to #{current_user.phone_number}: #{document_url}"
|
|
142
|
+
|
|
143
|
+
rescue KapsoClientRuby::Error => e
|
|
144
|
+
flash[:error] = "Failed to send document: #{e.message}"
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
redirect_to notifications_path
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# GET /notifications/message_status/:message_id
|
|
151
|
+
# Check status of a sent message
|
|
152
|
+
def message_status
|
|
153
|
+
message_id = params[:id]
|
|
154
|
+
service = KapsoMessageService.new
|
|
155
|
+
|
|
156
|
+
begin
|
|
157
|
+
status = service.get_message_status(message_id)
|
|
158
|
+
|
|
159
|
+
if status
|
|
160
|
+
render json: {
|
|
161
|
+
message_id: status['id'],
|
|
162
|
+
status: status['status'],
|
|
163
|
+
timestamp: status['timestamp'],
|
|
164
|
+
recipient_id: status['recipient_id']
|
|
165
|
+
}
|
|
166
|
+
else
|
|
167
|
+
render json: { error: 'Message not found' }, status: :not_found
|
|
168
|
+
end
|
|
169
|
+
rescue KapsoClientRuby::Error => e
|
|
170
|
+
render json: { error: e.message }, status: :unprocessable_entity
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# POST /notifications/bulk
|
|
175
|
+
# Send bulk messages (should be queued in production)
|
|
176
|
+
def send_bulk
|
|
177
|
+
recipients = params[:recipients]&.split(',')&.map(&:strip) || []
|
|
178
|
+
message = params[:message]
|
|
179
|
+
|
|
180
|
+
if recipients.empty? || message.blank?
|
|
181
|
+
flash[:error] = "Recipients and message are required"
|
|
182
|
+
redirect_to notifications_path
|
|
183
|
+
return
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# In production, this should be done via background jobs
|
|
187
|
+
successful_sends = 0
|
|
188
|
+
failed_sends = 0
|
|
189
|
+
|
|
190
|
+
recipients.each do |phone_number|
|
|
191
|
+
begin
|
|
192
|
+
service = KapsoMessageService.new
|
|
193
|
+
result = service.send_text(phone_number: phone_number, message: message)
|
|
194
|
+
|
|
195
|
+
if result
|
|
196
|
+
successful_sends += 1
|
|
197
|
+
Rails.logger.info "Bulk message sent to #{phone_number}"
|
|
198
|
+
else
|
|
199
|
+
failed_sends += 1
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Rate limiting - small delay between messages
|
|
203
|
+
sleep(0.5)
|
|
204
|
+
|
|
205
|
+
rescue KapsoClientRuby::Error => e
|
|
206
|
+
failed_sends += 1
|
|
207
|
+
Rails.logger.error "Bulk message failed for #{phone_number}: #{e.message}"
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
flash[:success] = "Bulk send complete: #{successful_sends} sent, #{failed_sends} failed"
|
|
212
|
+
redirect_to notifications_path
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
private
|
|
216
|
+
|
|
217
|
+
def ensure_phone_number
|
|
218
|
+
unless current_user.phone_number.present?
|
|
219
|
+
flash[:error] = "Please add a phone number to your profile first"
|
|
220
|
+
redirect_to edit_user_registration_path
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def notification_params
|
|
225
|
+
params.permit(:message, :template_name, :document_url, :filename, :caption, :recipients, template_params: {})
|
|
226
|
+
end
|
|
227
227
|
end
|