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
data/RAILS_INTEGRATION.md
CHANGED
|
@@ -1,478 +1,478 @@
|
|
|
1
|
-
# Rails Integration Guide
|
|
2
|
-
|
|
3
|
-
This guide shows you how to integrate KapsoClientRuby with your Rails application for sending WhatsApp messages through the Kapso API.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
Add the gem to your Gemfile:
|
|
8
|
-
|
|
9
|
-
```ruby
|
|
10
|
-
gem 'kapso-client-ruby'
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
Then run:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
bundle install
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Quick Setup with Generator
|
|
20
|
-
|
|
21
|
-
The easiest way to set up KapsoClientRuby in your Rails app is using the built-in generator:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
rails generate kapso_client_ruby:install
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
This will create:
|
|
28
|
-
- `config/initializers/kapso_client_ruby.rb` - Configuration file
|
|
29
|
-
- `app/controllers/kapso_webhooks_controller.rb` - Webhook handler
|
|
30
|
-
- `app/services/kapso_message_service.rb` - Service class for messaging
|
|
31
|
-
- `.env.example` - Environment variables template
|
|
32
|
-
- Webhook routes in `config/routes.rb`
|
|
33
|
-
|
|
34
|
-
## Manual Setup
|
|
35
|
-
|
|
36
|
-
If you prefer to set up manually:
|
|
37
|
-
|
|
38
|
-
### 1. Configuration
|
|
39
|
-
|
|
40
|
-
Create `config/initializers/kapso_client_ruby.rb`:
|
|
41
|
-
|
|
42
|
-
```ruby
|
|
43
|
-
KapsoClientRuby.configure do |config|
|
|
44
|
-
config.api_key = ENV['KAPSO_API_KEY']
|
|
45
|
-
config.phone_number_id = ENV['KAPSO_PHONE_NUMBER_ID']
|
|
46
|
-
config.business_account_id = ENV['KAPSO_BUSINESS_ACCOUNT_ID']
|
|
47
|
-
|
|
48
|
-
# Optional settings
|
|
49
|
-
config.debug = Rails.env.development?
|
|
50
|
-
config.logger = Rails.logger
|
|
51
|
-
config.timeout = 30
|
|
52
|
-
end
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### 2. Environment Variables
|
|
56
|
-
|
|
57
|
-
Add to your `.env` file:
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
KAPSO_API_KEY=your_api_key_here
|
|
61
|
-
KAPSO_PHONE_NUMBER_ID=your_phone_number_id_here
|
|
62
|
-
KAPSO_BUSINESS_ACCOUNT_ID=your_business_account_id_here
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### 3. Service Class
|
|
66
|
-
|
|
67
|
-
Create `app/services/kapso_message_service.rb`:
|
|
68
|
-
|
|
69
|
-
```ruby
|
|
70
|
-
class KapsoMessageService
|
|
71
|
-
def initialize
|
|
72
|
-
@service = KapsoClientRuby::Rails::Service.new
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def send_welcome_message(user)
|
|
76
|
-
@service.send_template_message(
|
|
77
|
-
to: user.phone_number,
|
|
78
|
-
template_name: 'welcome_message',
|
|
79
|
-
language: 'en',
|
|
80
|
-
components: [
|
|
81
|
-
{
|
|
82
|
-
type: 'body',
|
|
83
|
-
parameters: [
|
|
84
|
-
{ type: 'text', text: user.first_name }
|
|
85
|
-
]
|
|
86
|
-
}
|
|
87
|
-
]
|
|
88
|
-
)
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## Usage Examples
|
|
94
|
-
|
|
95
|
-
### Sending Messages in Controllers
|
|
96
|
-
|
|
97
|
-
```ruby
|
|
98
|
-
class UsersController < ApplicationController
|
|
99
|
-
def create
|
|
100
|
-
@user = User.new(user_params)
|
|
101
|
-
|
|
102
|
-
if @user.save
|
|
103
|
-
# Send welcome message
|
|
104
|
-
KapsoMessageService.new.send_welcome_message(@user)
|
|
105
|
-
redirect_to @user, notice: 'User created and welcome message sent!'
|
|
106
|
-
else
|
|
107
|
-
render :new
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### Using in Models
|
|
114
|
-
|
|
115
|
-
```ruby
|
|
116
|
-
class Order < ApplicationRecord
|
|
117
|
-
belongs_to :user
|
|
118
|
-
|
|
119
|
-
after_create :send_confirmation_message
|
|
120
|
-
|
|
121
|
-
private
|
|
122
|
-
|
|
123
|
-
def send_confirmation_message
|
|
124
|
-
return unless user.phone_number.present?
|
|
125
|
-
|
|
126
|
-
KapsoMessageService.new.send_order_confirmation(self)
|
|
127
|
-
rescue KapsoClientRuby::Error => e
|
|
128
|
-
Rails.logger.error "Failed to send order confirmation: #{e.message}"
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### Background Jobs
|
|
134
|
-
|
|
135
|
-
For better performance, send messages in background jobs:
|
|
136
|
-
|
|
137
|
-
```ruby
|
|
138
|
-
class SendWhatsAppMessageJob < ApplicationJob
|
|
139
|
-
queue_as :default
|
|
140
|
-
|
|
141
|
-
def perform(phone_number, message_type, **options)
|
|
142
|
-
service = KapsoMessageService.new
|
|
143
|
-
|
|
144
|
-
case message_type
|
|
145
|
-
when 'welcome'
|
|
146
|
-
service.send_welcome_message(options[:user])
|
|
147
|
-
when 'order_confirmation'
|
|
148
|
-
service.send_order_confirmation(options[:order])
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
# Usage in controller:
|
|
154
|
-
SendWhatsAppMessageJob.perform_later(user.phone_number, 'welcome', user: user)
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Webhook Integration
|
|
158
|
-
|
|
159
|
-
### 1. Webhook Controller
|
|
160
|
-
|
|
161
|
-
The generated webhook controller handles incoming WhatsApp messages and status updates:
|
|
162
|
-
|
|
163
|
-
```ruby
|
|
164
|
-
class KapsoWebhooksController < ApplicationController
|
|
165
|
-
skip_before_action :verify_authenticity_token
|
|
166
|
-
|
|
167
|
-
def verify
|
|
168
|
-
# Webhook verification logic
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def create
|
|
172
|
-
service = KapsoClientRuby::Rails::Service.new
|
|
173
|
-
service.process_webhook(params.to_unsafe_h)
|
|
174
|
-
render json: { status: 'ok' }
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### 2. Routes
|
|
180
|
-
|
|
181
|
-
Add to `config/routes.rb`:
|
|
182
|
-
|
|
183
|
-
```ruby
|
|
184
|
-
post '/webhooks/kapso', to: 'kapso_webhooks#create'
|
|
185
|
-
get '/webhooks/kapso', to: 'kapso_webhooks#verify'
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### 3. Event Listeners
|
|
189
|
-
|
|
190
|
-
Subscribe to WhatsApp events in your initializer:
|
|
191
|
-
|
|
192
|
-
```ruby
|
|
193
|
-
# In config/initializers/kapso_client_ruby.rb
|
|
194
|
-
|
|
195
|
-
ActiveSupport::Notifications.subscribe('kapso.message_received') do |name, start, finish, id, payload|
|
|
196
|
-
message = payload[:message]
|
|
197
|
-
|
|
198
|
-
# Handle incoming message
|
|
199
|
-
HandleIncomingMessageJob.perform_later(message)
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
ActiveSupport::Notifications.subscribe('kapso.message_status_updated') do |name, start, finish, id, payload|
|
|
203
|
-
status = payload[:status]
|
|
204
|
-
|
|
205
|
-
# Update message status in database
|
|
206
|
-
UpdateMessageStatusJob.perform_later(status)
|
|
207
|
-
end
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
## Available Rake Tasks
|
|
211
|
-
|
|
212
|
-
```bash
|
|
213
|
-
# Test configuration and send test message
|
|
214
|
-
rails kapso:test
|
|
215
|
-
|
|
216
|
-
# List available templates
|
|
217
|
-
rails kapso:templates
|
|
218
|
-
|
|
219
|
-
# Check message status
|
|
220
|
-
rails kapso:message_status[message_id]
|
|
221
|
-
|
|
222
|
-
# Validate webhook configuration
|
|
223
|
-
rails kapso:validate_webhook
|
|
224
|
-
|
|
225
|
-
# Generate sample .env file
|
|
226
|
-
rails kapso:sample_env
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
## Configuration Options
|
|
230
|
-
|
|
231
|
-
All configuration options available in the Rails initializer:
|
|
232
|
-
|
|
233
|
-
```ruby
|
|
234
|
-
KapsoClientRuby.configure do |config|
|
|
235
|
-
# Required
|
|
236
|
-
config.api_key = ENV['KAPSO_API_KEY']
|
|
237
|
-
config.phone_number_id = ENV['KAPSO_PHONE_NUMBER_ID']
|
|
238
|
-
config.business_account_id = ENV['KAPSO_BUSINESS_ACCOUNT_ID']
|
|
239
|
-
|
|
240
|
-
# API Configuration
|
|
241
|
-
config.api_host = ENV.fetch('KAPSO_API_HOST', 'https://graph.facebook.com')
|
|
242
|
-
config.api_version = ENV.fetch('KAPSO_API_VERSION', 'v18.0')
|
|
243
|
-
config.timeout = ENV.fetch('KAPSO_TIMEOUT', 30).to_i
|
|
244
|
-
|
|
245
|
-
# Logging and Debug
|
|
246
|
-
config.debug = Rails.env.development?
|
|
247
|
-
config.logger = Rails.logger
|
|
248
|
-
|
|
249
|
-
# Retry Configuration
|
|
250
|
-
config.retry_on_failure = true
|
|
251
|
-
config.max_retries = 3
|
|
252
|
-
end
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
## Rails-Specific Features
|
|
256
|
-
|
|
257
|
-
### 1. ActiveSupport Notifications
|
|
258
|
-
|
|
259
|
-
The gem automatically publishes events that you can subscribe to:
|
|
260
|
-
|
|
261
|
-
- `kapso.message_received` - When a WhatsApp message is received
|
|
262
|
-
- `kapso.message_status_updated` - When message delivery status changes
|
|
263
|
-
- `kapso.template_status_updated` - When template approval status changes
|
|
264
|
-
|
|
265
|
-
### 2. Rails Logger Integration
|
|
266
|
-
|
|
267
|
-
All Kapso operations automatically log to Rails.logger with appropriate log levels.
|
|
268
|
-
|
|
269
|
-
### 3. Environment-Based Configuration
|
|
270
|
-
|
|
271
|
-
The gem respects Rails environments and can be configured differently for development, test, and production.
|
|
272
|
-
|
|
273
|
-
### 4. Rails Service Pattern
|
|
274
|
-
|
|
275
|
-
The `KapsoClientRuby::Rails::Service` class follows Rails service object patterns and integrates seamlessly with Rails applications.
|
|
276
|
-
|
|
277
|
-
## Testing
|
|
278
|
-
|
|
279
|
-
### RSpec Integration
|
|
280
|
-
|
|
281
|
-
```ruby
|
|
282
|
-
# spec/rails_helper.rb
|
|
283
|
-
RSpec.configure do |config|
|
|
284
|
-
config.before(:each) do
|
|
285
|
-
# Mock Kapso API calls in tests
|
|
286
|
-
allow_any_instance_of(KapsoClientRuby::Client).to receive(:send_request)
|
|
287
|
-
.and_return({ 'messages' => [{ 'id' => 'test_message_id' }] })
|
|
288
|
-
end
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
# spec/services/kapso_message_service_spec.rb
|
|
292
|
-
RSpec.describe KapsoMessageService do
|
|
293
|
-
let(:user) { create(:user, phone_number: '+1234567890') }
|
|
294
|
-
let(:service) { described_class.new }
|
|
295
|
-
|
|
296
|
-
describe '#send_welcome_message' do
|
|
297
|
-
it 'sends a welcome message to the user' do
|
|
298
|
-
expect(service).to receive(:send_template_message)
|
|
299
|
-
.with(hash_including(to: user.phone_number))
|
|
300
|
-
|
|
301
|
-
service.send_welcome_message(user)
|
|
302
|
-
end
|
|
303
|
-
end
|
|
304
|
-
end
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### Test Configuration
|
|
308
|
-
|
|
309
|
-
```ruby
|
|
310
|
-
# config/environments/test.rb
|
|
311
|
-
config.kapso.debug = false
|
|
312
|
-
config.kapso.logger = Logger.new('/dev/null') # Silence logs in tests
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
## Error Handling
|
|
316
|
-
|
|
317
|
-
```ruby
|
|
318
|
-
class KapsoMessageService
|
|
319
|
-
def send_message_with_retry(phone_number, message)
|
|
320
|
-
retries = 0
|
|
321
|
-
max_retries = 3
|
|
322
|
-
|
|
323
|
-
begin
|
|
324
|
-
send_text_message(to: phone_number, text: message)
|
|
325
|
-
rescue KapsoClientRuby::RateLimitError => e
|
|
326
|
-
if retries < max_retries
|
|
327
|
-
retries += 1
|
|
328
|
-
sleep(2 ** retries) # Exponential backoff
|
|
329
|
-
retry
|
|
330
|
-
else
|
|
331
|
-
Rails.logger.error "Rate limit exceeded after #{max_retries} retries: #{e.message}"
|
|
332
|
-
raise
|
|
333
|
-
end
|
|
334
|
-
rescue KapsoClientRuby::Error => e
|
|
335
|
-
Rails.logger.error "Kapso API error: #{e.message}"
|
|
336
|
-
# Handle gracefully or re-raise depending on your needs
|
|
337
|
-
nil
|
|
338
|
-
end
|
|
339
|
-
end
|
|
340
|
-
end
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
## Production Considerations
|
|
344
|
-
|
|
345
|
-
### 1. Environment Variables
|
|
346
|
-
|
|
347
|
-
Use Rails credentials or a secure environment variable management system:
|
|
348
|
-
|
|
349
|
-
```bash
|
|
350
|
-
# Using Rails credentials
|
|
351
|
-
rails credentials:edit
|
|
352
|
-
|
|
353
|
-
# Add:
|
|
354
|
-
kapso:
|
|
355
|
-
api_key: your_actual_api_key
|
|
356
|
-
phone_number_id: your_phone_number_id
|
|
357
|
-
business_account_id: your_business_account_id
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
```ruby
|
|
361
|
-
# In initializer
|
|
362
|
-
config.api_key = Rails.application.credentials.dig(:kapso, :api_key)
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
### 2. Background Processing
|
|
366
|
-
|
|
367
|
-
Always use background jobs for message sending in production:
|
|
368
|
-
|
|
369
|
-
```ruby
|
|
370
|
-
class User < ApplicationRecord
|
|
371
|
-
after_create :send_welcome_message_async
|
|
372
|
-
|
|
373
|
-
private
|
|
374
|
-
|
|
375
|
-
def send_welcome_message_async
|
|
376
|
-
SendWelcomeMessageJob.perform_later(self)
|
|
377
|
-
end
|
|
378
|
-
end
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
### 3. Rate Limiting
|
|
382
|
-
|
|
383
|
-
Implement rate limiting to avoid hitting API limits:
|
|
384
|
-
|
|
385
|
-
```ruby
|
|
386
|
-
class KapsoMessageService
|
|
387
|
-
include ActionController::Helpers
|
|
388
|
-
|
|
389
|
-
def send_message(phone_number, message)
|
|
390
|
-
# Check rate limit before sending
|
|
391
|
-
cache_key = "kapso_rate_limit:#{phone_number}"
|
|
392
|
-
|
|
393
|
-
if Rails.cache.read(cache_key).to_i >= 10 # 10 messages per hour
|
|
394
|
-
raise "Rate limit exceeded for #{phone_number}"
|
|
395
|
-
end
|
|
396
|
-
|
|
397
|
-
result = @service.send_text_message(to: phone_number, text: message)
|
|
398
|
-
|
|
399
|
-
# Increment counter
|
|
400
|
-
Rails.cache.increment(cache_key, 1, expires_in: 1.hour)
|
|
401
|
-
|
|
402
|
-
result
|
|
403
|
-
end
|
|
404
|
-
end
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
### 4. Monitoring and Alerting
|
|
408
|
-
|
|
409
|
-
```ruby
|
|
410
|
-
# In initializer, add error tracking
|
|
411
|
-
ActiveSupport::Notifications.subscribe('kapso.error') do |name, start, finish, id, payload|
|
|
412
|
-
error = payload[:error]
|
|
413
|
-
|
|
414
|
-
# Send to error tracking service
|
|
415
|
-
Bugsnag.notify(error) if defined?(Bugsnag)
|
|
416
|
-
Sentry.capture_exception(error) if defined?(Sentry)
|
|
417
|
-
end
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
## Troubleshooting
|
|
421
|
-
|
|
422
|
-
### Common Issues
|
|
423
|
-
|
|
424
|
-
1. **Invalid Phone Number Format**
|
|
425
|
-
```ruby
|
|
426
|
-
# Ensure phone numbers are in E.164 format
|
|
427
|
-
phone_number = "+1#{user.phone.gsub(/\D/, '')}"
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
2. **Missing Template Components**
|
|
431
|
-
```ruby
|
|
432
|
-
# Always include required template parameters
|
|
433
|
-
components = [
|
|
434
|
-
{
|
|
435
|
-
type: 'body',
|
|
436
|
-
parameters: [
|
|
437
|
-
{ type: 'text', text: user.name }
|
|
438
|
-
]
|
|
439
|
-
}
|
|
440
|
-
]
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
3. **Webhook Verification Failures**
|
|
444
|
-
```ruby
|
|
445
|
-
# Make sure webhook verification token matches
|
|
446
|
-
verify_token = params['hub.verify_token']
|
|
447
|
-
expected_token = ENV['KAPSO_WEBHOOK_VERIFY_TOKEN']
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
### Debug Mode
|
|
451
|
-
|
|
452
|
-
Enable debug mode in development:
|
|
453
|
-
|
|
454
|
-
```ruby
|
|
455
|
-
# config/environments/development.rb
|
|
456
|
-
config.kapso.debug = true
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
This will log all API requests and responses to help with debugging.
|
|
460
|
-
|
|
461
|
-
## Support
|
|
462
|
-
|
|
463
|
-
For issues specific to Rails integration, please check:
|
|
464
|
-
|
|
465
|
-
1. Rails logs for detailed error messages
|
|
466
|
-
2. Kapso API documentation
|
|
467
|
-
3. GitHub issues: https://github.com/PabloB07/kapso-client-ruby/issues
|
|
468
|
-
|
|
469
|
-
## Contributing
|
|
470
|
-
|
|
471
|
-
To contribute to Rails integration features:
|
|
472
|
-
|
|
473
|
-
1. Fork the repository
|
|
474
|
-
2. Create a feature branch
|
|
475
|
-
3. Add tests for Rails-specific functionality
|
|
476
|
-
4. Submit a pull request
|
|
477
|
-
|
|
1
|
+
# Rails Integration Guide
|
|
2
|
+
|
|
3
|
+
This guide shows you how to integrate KapsoClientRuby with your Rails application for sending WhatsApp messages through the Kapso API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add the gem to your Gemfile:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'kapso-client-ruby'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then run:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bundle install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Setup with Generator
|
|
20
|
+
|
|
21
|
+
The easiest way to set up KapsoClientRuby in your Rails app is using the built-in generator:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
rails generate kapso_client_ruby:install
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
This will create:
|
|
28
|
+
- `config/initializers/kapso_client_ruby.rb` - Configuration file
|
|
29
|
+
- `app/controllers/kapso_webhooks_controller.rb` - Webhook handler
|
|
30
|
+
- `app/services/kapso_message_service.rb` - Service class for messaging
|
|
31
|
+
- `.env.example` - Environment variables template
|
|
32
|
+
- Webhook routes in `config/routes.rb`
|
|
33
|
+
|
|
34
|
+
## Manual Setup
|
|
35
|
+
|
|
36
|
+
If you prefer to set up manually:
|
|
37
|
+
|
|
38
|
+
### 1. Configuration
|
|
39
|
+
|
|
40
|
+
Create `config/initializers/kapso_client_ruby.rb`:
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
KapsoClientRuby.configure do |config|
|
|
44
|
+
config.api_key = ENV['KAPSO_API_KEY']
|
|
45
|
+
config.phone_number_id = ENV['KAPSO_PHONE_NUMBER_ID']
|
|
46
|
+
config.business_account_id = ENV['KAPSO_BUSINESS_ACCOUNT_ID']
|
|
47
|
+
|
|
48
|
+
# Optional settings
|
|
49
|
+
config.debug = Rails.env.development?
|
|
50
|
+
config.logger = Rails.logger
|
|
51
|
+
config.timeout = 30
|
|
52
|
+
end
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 2. Environment Variables
|
|
56
|
+
|
|
57
|
+
Add to your `.env` file:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
KAPSO_API_KEY=your_api_key_here
|
|
61
|
+
KAPSO_PHONE_NUMBER_ID=your_phone_number_id_here
|
|
62
|
+
KAPSO_BUSINESS_ACCOUNT_ID=your_business_account_id_here
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 3. Service Class
|
|
66
|
+
|
|
67
|
+
Create `app/services/kapso_message_service.rb`:
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
class KapsoMessageService
|
|
71
|
+
def initialize
|
|
72
|
+
@service = KapsoClientRuby::Rails::Service.new
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def send_welcome_message(user)
|
|
76
|
+
@service.send_template_message(
|
|
77
|
+
to: user.phone_number,
|
|
78
|
+
template_name: 'welcome_message',
|
|
79
|
+
language: 'en',
|
|
80
|
+
components: [
|
|
81
|
+
{
|
|
82
|
+
type: 'body',
|
|
83
|
+
parameters: [
|
|
84
|
+
{ type: 'text', text: user.first_name }
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Usage Examples
|
|
94
|
+
|
|
95
|
+
### Sending Messages in Controllers
|
|
96
|
+
|
|
97
|
+
```ruby
|
|
98
|
+
class UsersController < ApplicationController
|
|
99
|
+
def create
|
|
100
|
+
@user = User.new(user_params)
|
|
101
|
+
|
|
102
|
+
if @user.save
|
|
103
|
+
# Send welcome message
|
|
104
|
+
KapsoMessageService.new.send_welcome_message(@user)
|
|
105
|
+
redirect_to @user, notice: 'User created and welcome message sent!'
|
|
106
|
+
else
|
|
107
|
+
render :new
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Using in Models
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
class Order < ApplicationRecord
|
|
117
|
+
belongs_to :user
|
|
118
|
+
|
|
119
|
+
after_create :send_confirmation_message
|
|
120
|
+
|
|
121
|
+
private
|
|
122
|
+
|
|
123
|
+
def send_confirmation_message
|
|
124
|
+
return unless user.phone_number.present?
|
|
125
|
+
|
|
126
|
+
KapsoMessageService.new.send_order_confirmation(self)
|
|
127
|
+
rescue KapsoClientRuby::Error => e
|
|
128
|
+
Rails.logger.error "Failed to send order confirmation: #{e.message}"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Background Jobs
|
|
134
|
+
|
|
135
|
+
For better performance, send messages in background jobs:
|
|
136
|
+
|
|
137
|
+
```ruby
|
|
138
|
+
class SendWhatsAppMessageJob < ApplicationJob
|
|
139
|
+
queue_as :default
|
|
140
|
+
|
|
141
|
+
def perform(phone_number, message_type, **options)
|
|
142
|
+
service = KapsoMessageService.new
|
|
143
|
+
|
|
144
|
+
case message_type
|
|
145
|
+
when 'welcome'
|
|
146
|
+
service.send_welcome_message(options[:user])
|
|
147
|
+
when 'order_confirmation'
|
|
148
|
+
service.send_order_confirmation(options[:order])
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Usage in controller:
|
|
154
|
+
SendWhatsAppMessageJob.perform_later(user.phone_number, 'welcome', user: user)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Webhook Integration
|
|
158
|
+
|
|
159
|
+
### 1. Webhook Controller
|
|
160
|
+
|
|
161
|
+
The generated webhook controller handles incoming WhatsApp messages and status updates:
|
|
162
|
+
|
|
163
|
+
```ruby
|
|
164
|
+
class KapsoWebhooksController < ApplicationController
|
|
165
|
+
skip_before_action :verify_authenticity_token
|
|
166
|
+
|
|
167
|
+
def verify
|
|
168
|
+
# Webhook verification logic
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def create
|
|
172
|
+
service = KapsoClientRuby::Rails::Service.new
|
|
173
|
+
service.process_webhook(params.to_unsafe_h)
|
|
174
|
+
render json: { status: 'ok' }
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 2. Routes
|
|
180
|
+
|
|
181
|
+
Add to `config/routes.rb`:
|
|
182
|
+
|
|
183
|
+
```ruby
|
|
184
|
+
post '/webhooks/kapso', to: 'kapso_webhooks#create'
|
|
185
|
+
get '/webhooks/kapso', to: 'kapso_webhooks#verify'
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### 3. Event Listeners
|
|
189
|
+
|
|
190
|
+
Subscribe to WhatsApp events in your initializer:
|
|
191
|
+
|
|
192
|
+
```ruby
|
|
193
|
+
# In config/initializers/kapso_client_ruby.rb
|
|
194
|
+
|
|
195
|
+
ActiveSupport::Notifications.subscribe('kapso.message_received') do |name, start, finish, id, payload|
|
|
196
|
+
message = payload[:message]
|
|
197
|
+
|
|
198
|
+
# Handle incoming message
|
|
199
|
+
HandleIncomingMessageJob.perform_later(message)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
ActiveSupport::Notifications.subscribe('kapso.message_status_updated') do |name, start, finish, id, payload|
|
|
203
|
+
status = payload[:status]
|
|
204
|
+
|
|
205
|
+
# Update message status in database
|
|
206
|
+
UpdateMessageStatusJob.perform_later(status)
|
|
207
|
+
end
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Available Rake Tasks
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# Test configuration and send test message
|
|
214
|
+
rails kapso:test
|
|
215
|
+
|
|
216
|
+
# List available templates
|
|
217
|
+
rails kapso:templates
|
|
218
|
+
|
|
219
|
+
# Check message status
|
|
220
|
+
rails kapso:message_status[message_id]
|
|
221
|
+
|
|
222
|
+
# Validate webhook configuration
|
|
223
|
+
rails kapso:validate_webhook
|
|
224
|
+
|
|
225
|
+
# Generate sample .env file
|
|
226
|
+
rails kapso:sample_env
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Configuration Options
|
|
230
|
+
|
|
231
|
+
All configuration options available in the Rails initializer:
|
|
232
|
+
|
|
233
|
+
```ruby
|
|
234
|
+
KapsoClientRuby.configure do |config|
|
|
235
|
+
# Required
|
|
236
|
+
config.api_key = ENV['KAPSO_API_KEY']
|
|
237
|
+
config.phone_number_id = ENV['KAPSO_PHONE_NUMBER_ID']
|
|
238
|
+
config.business_account_id = ENV['KAPSO_BUSINESS_ACCOUNT_ID']
|
|
239
|
+
|
|
240
|
+
# API Configuration
|
|
241
|
+
config.api_host = ENV.fetch('KAPSO_API_HOST', 'https://graph.facebook.com')
|
|
242
|
+
config.api_version = ENV.fetch('KAPSO_API_VERSION', 'v18.0')
|
|
243
|
+
config.timeout = ENV.fetch('KAPSO_TIMEOUT', 30).to_i
|
|
244
|
+
|
|
245
|
+
# Logging and Debug
|
|
246
|
+
config.debug = Rails.env.development?
|
|
247
|
+
config.logger = Rails.logger
|
|
248
|
+
|
|
249
|
+
# Retry Configuration
|
|
250
|
+
config.retry_on_failure = true
|
|
251
|
+
config.max_retries = 3
|
|
252
|
+
end
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Rails-Specific Features
|
|
256
|
+
|
|
257
|
+
### 1. ActiveSupport Notifications
|
|
258
|
+
|
|
259
|
+
The gem automatically publishes events that you can subscribe to:
|
|
260
|
+
|
|
261
|
+
- `kapso.message_received` - When a WhatsApp message is received
|
|
262
|
+
- `kapso.message_status_updated` - When message delivery status changes
|
|
263
|
+
- `kapso.template_status_updated` - When template approval status changes
|
|
264
|
+
|
|
265
|
+
### 2. Rails Logger Integration
|
|
266
|
+
|
|
267
|
+
All Kapso operations automatically log to Rails.logger with appropriate log levels.
|
|
268
|
+
|
|
269
|
+
### 3. Environment-Based Configuration
|
|
270
|
+
|
|
271
|
+
The gem respects Rails environments and can be configured differently for development, test, and production.
|
|
272
|
+
|
|
273
|
+
### 4. Rails Service Pattern
|
|
274
|
+
|
|
275
|
+
The `KapsoClientRuby::Rails::Service` class follows Rails service object patterns and integrates seamlessly with Rails applications.
|
|
276
|
+
|
|
277
|
+
## Testing
|
|
278
|
+
|
|
279
|
+
### RSpec Integration
|
|
280
|
+
|
|
281
|
+
```ruby
|
|
282
|
+
# spec/rails_helper.rb
|
|
283
|
+
RSpec.configure do |config|
|
|
284
|
+
config.before(:each) do
|
|
285
|
+
# Mock Kapso API calls in tests
|
|
286
|
+
allow_any_instance_of(KapsoClientRuby::Client).to receive(:send_request)
|
|
287
|
+
.and_return({ 'messages' => [{ 'id' => 'test_message_id' }] })
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
# spec/services/kapso_message_service_spec.rb
|
|
292
|
+
RSpec.describe KapsoMessageService do
|
|
293
|
+
let(:user) { create(:user, phone_number: '+1234567890') }
|
|
294
|
+
let(:service) { described_class.new }
|
|
295
|
+
|
|
296
|
+
describe '#send_welcome_message' do
|
|
297
|
+
it 'sends a welcome message to the user' do
|
|
298
|
+
expect(service).to receive(:send_template_message)
|
|
299
|
+
.with(hash_including(to: user.phone_number))
|
|
300
|
+
|
|
301
|
+
service.send_welcome_message(user)
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Test Configuration
|
|
308
|
+
|
|
309
|
+
```ruby
|
|
310
|
+
# config/environments/test.rb
|
|
311
|
+
config.kapso.debug = false
|
|
312
|
+
config.kapso.logger = Logger.new('/dev/null') # Silence logs in tests
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Error Handling
|
|
316
|
+
|
|
317
|
+
```ruby
|
|
318
|
+
class KapsoMessageService
|
|
319
|
+
def send_message_with_retry(phone_number, message)
|
|
320
|
+
retries = 0
|
|
321
|
+
max_retries = 3
|
|
322
|
+
|
|
323
|
+
begin
|
|
324
|
+
send_text_message(to: phone_number, text: message)
|
|
325
|
+
rescue KapsoClientRuby::RateLimitError => e
|
|
326
|
+
if retries < max_retries
|
|
327
|
+
retries += 1
|
|
328
|
+
sleep(2 ** retries) # Exponential backoff
|
|
329
|
+
retry
|
|
330
|
+
else
|
|
331
|
+
Rails.logger.error "Rate limit exceeded after #{max_retries} retries: #{e.message}"
|
|
332
|
+
raise
|
|
333
|
+
end
|
|
334
|
+
rescue KapsoClientRuby::Error => e
|
|
335
|
+
Rails.logger.error "Kapso API error: #{e.message}"
|
|
336
|
+
# Handle gracefully or re-raise depending on your needs
|
|
337
|
+
nil
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Production Considerations
|
|
344
|
+
|
|
345
|
+
### 1. Environment Variables
|
|
346
|
+
|
|
347
|
+
Use Rails credentials or a secure environment variable management system:
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
# Using Rails credentials
|
|
351
|
+
rails credentials:edit
|
|
352
|
+
|
|
353
|
+
# Add:
|
|
354
|
+
kapso:
|
|
355
|
+
api_key: your_actual_api_key
|
|
356
|
+
phone_number_id: your_phone_number_id
|
|
357
|
+
business_account_id: your_business_account_id
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
```ruby
|
|
361
|
+
# In initializer
|
|
362
|
+
config.api_key = Rails.application.credentials.dig(:kapso, :api_key)
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### 2. Background Processing
|
|
366
|
+
|
|
367
|
+
Always use background jobs for message sending in production:
|
|
368
|
+
|
|
369
|
+
```ruby
|
|
370
|
+
class User < ApplicationRecord
|
|
371
|
+
after_create :send_welcome_message_async
|
|
372
|
+
|
|
373
|
+
private
|
|
374
|
+
|
|
375
|
+
def send_welcome_message_async
|
|
376
|
+
SendWelcomeMessageJob.perform_later(self)
|
|
377
|
+
end
|
|
378
|
+
end
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### 3. Rate Limiting
|
|
382
|
+
|
|
383
|
+
Implement rate limiting to avoid hitting API limits:
|
|
384
|
+
|
|
385
|
+
```ruby
|
|
386
|
+
class KapsoMessageService
|
|
387
|
+
include ActionController::Helpers
|
|
388
|
+
|
|
389
|
+
def send_message(phone_number, message)
|
|
390
|
+
# Check rate limit before sending
|
|
391
|
+
cache_key = "kapso_rate_limit:#{phone_number}"
|
|
392
|
+
|
|
393
|
+
if Rails.cache.read(cache_key).to_i >= 10 # 10 messages per hour
|
|
394
|
+
raise "Rate limit exceeded for #{phone_number}"
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
result = @service.send_text_message(to: phone_number, text: message)
|
|
398
|
+
|
|
399
|
+
# Increment counter
|
|
400
|
+
Rails.cache.increment(cache_key, 1, expires_in: 1.hour)
|
|
401
|
+
|
|
402
|
+
result
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### 4. Monitoring and Alerting
|
|
408
|
+
|
|
409
|
+
```ruby
|
|
410
|
+
# In initializer, add error tracking
|
|
411
|
+
ActiveSupport::Notifications.subscribe('kapso.error') do |name, start, finish, id, payload|
|
|
412
|
+
error = payload[:error]
|
|
413
|
+
|
|
414
|
+
# Send to error tracking service
|
|
415
|
+
Bugsnag.notify(error) if defined?(Bugsnag)
|
|
416
|
+
Sentry.capture_exception(error) if defined?(Sentry)
|
|
417
|
+
end
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## Troubleshooting
|
|
421
|
+
|
|
422
|
+
### Common Issues
|
|
423
|
+
|
|
424
|
+
1. **Invalid Phone Number Format**
|
|
425
|
+
```ruby
|
|
426
|
+
# Ensure phone numbers are in E.164 format
|
|
427
|
+
phone_number = "+1#{user.phone.gsub(/\D/, '')}"
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
2. **Missing Template Components**
|
|
431
|
+
```ruby
|
|
432
|
+
# Always include required template parameters
|
|
433
|
+
components = [
|
|
434
|
+
{
|
|
435
|
+
type: 'body',
|
|
436
|
+
parameters: [
|
|
437
|
+
{ type: 'text', text: user.name }
|
|
438
|
+
]
|
|
439
|
+
}
|
|
440
|
+
]
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
3. **Webhook Verification Failures**
|
|
444
|
+
```ruby
|
|
445
|
+
# Make sure webhook verification token matches
|
|
446
|
+
verify_token = params['hub.verify_token']
|
|
447
|
+
expected_token = ENV['KAPSO_WEBHOOK_VERIFY_TOKEN']
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Debug Mode
|
|
451
|
+
|
|
452
|
+
Enable debug mode in development:
|
|
453
|
+
|
|
454
|
+
```ruby
|
|
455
|
+
# config/environments/development.rb
|
|
456
|
+
config.kapso.debug = true
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
This will log all API requests and responses to help with debugging.
|
|
460
|
+
|
|
461
|
+
## Support
|
|
462
|
+
|
|
463
|
+
For issues specific to Rails integration, please check:
|
|
464
|
+
|
|
465
|
+
1. Rails logs for detailed error messages
|
|
466
|
+
2. Kapso API documentation
|
|
467
|
+
3. GitHub issues: https://github.com/PabloB07/kapso-client-ruby/issues
|
|
468
|
+
|
|
469
|
+
## Contributing
|
|
470
|
+
|
|
471
|
+
To contribute to Rails integration features:
|
|
472
|
+
|
|
473
|
+
1. Fork the repository
|
|
474
|
+
2. Create a feature branch
|
|
475
|
+
3. Add tests for Rails-specific functionality
|
|
476
|
+
4. Submit a pull request
|
|
477
|
+
|
|
478
478
|
The Rails integration code is located in `lib/kapso_client_ruby/rails/`.
|