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,76 +1,76 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'rails/generators'
|
|
4
|
-
|
|
5
|
-
module KapsoClientRuby
|
|
6
|
-
module Rails
|
|
7
|
-
module Generators
|
|
8
|
-
class InstallGenerator < ::Rails::Generators::Base
|
|
9
|
-
source_root File.expand_path('templates', __dir__)
|
|
10
|
-
|
|
11
|
-
desc 'Install KapsoClientRuby in a Rails application'
|
|
12
|
-
|
|
13
|
-
def create_initializer
|
|
14
|
-
template 'initializer.rb.erb', 'config/initializers/kapso_client_ruby.rb'
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def create_env_example
|
|
18
|
-
template 'env.erb', '.env.example'
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def create_webhook_controller
|
|
22
|
-
template 'webhook_controller.rb.erb', 'app/controllers/kapso_webhooks_controller.rb'
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def create_service_example
|
|
26
|
-
template 'message_service.rb.erb', 'app/services/kapso_message_service.rb'
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def add_routes
|
|
30
|
-
route <<~RUBY
|
|
31
|
-
# Kapso webhook endpoint
|
|
32
|
-
post '/webhooks/kapso', to: 'kapso_webhooks#create'
|
|
33
|
-
get '/webhooks/kapso', to: 'kapso_webhooks#verify' # For webhook verification
|
|
34
|
-
RUBY
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def show_readme
|
|
38
|
-
say <<~MESSAGE
|
|
39
|
-
|
|
40
|
-
KapsoClientRuby has been successfully installed!
|
|
41
|
-
|
|
42
|
-
Next steps:
|
|
43
|
-
1. Add your Kapso credentials to your environment variables:
|
|
44
|
-
- KAPSO_API_KEY
|
|
45
|
-
- KAPSO_PHONE_NUMBER_ID
|
|
46
|
-
- KAPSO_BUSINESS_ACCOUNT_ID
|
|
47
|
-
|
|
48
|
-
2. Review and customize the generated files:
|
|
49
|
-
- config/initializers/kapso_client_ruby.rb
|
|
50
|
-
- app/controllers/kapso_webhooks_controller.rb
|
|
51
|
-
- app/services/kapso_message_service.rb
|
|
52
|
-
|
|
53
|
-
3. Set up your webhook URL in the Kapso dashboard:
|
|
54
|
-
https://yourapp.com/webhooks/kapso
|
|
55
|
-
|
|
56
|
-
4. Test the integration:
|
|
57
|
-
rails runner "KapsoMessageService.new.send_test_message"
|
|
58
|
-
|
|
59
|
-
For more information, see: https://github.com/PabloB07/kapso-client-ruby
|
|
60
|
-
|
|
61
|
-
MESSAGE
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
private
|
|
65
|
-
|
|
66
|
-
def application_name
|
|
67
|
-
if defined?(Rails) && Rails.application
|
|
68
|
-
Rails.application.class.name.split('::').first
|
|
69
|
-
else
|
|
70
|
-
'YourApp'
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails/generators'
|
|
4
|
+
|
|
5
|
+
module KapsoClientRuby
|
|
6
|
+
module Rails
|
|
7
|
+
module Generators
|
|
8
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
9
|
+
source_root File.expand_path('templates', __dir__)
|
|
10
|
+
|
|
11
|
+
desc 'Install KapsoClientRuby in a Rails application'
|
|
12
|
+
|
|
13
|
+
def create_initializer
|
|
14
|
+
template 'initializer.rb.erb', 'config/initializers/kapso_client_ruby.rb'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def create_env_example
|
|
18
|
+
template 'env.erb', '.env.example'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def create_webhook_controller
|
|
22
|
+
template 'webhook_controller.rb.erb', 'app/controllers/kapso_webhooks_controller.rb'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def create_service_example
|
|
26
|
+
template 'message_service.rb.erb', 'app/services/kapso_message_service.rb'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def add_routes
|
|
30
|
+
route <<~RUBY
|
|
31
|
+
# Kapso webhook endpoint
|
|
32
|
+
post '/webhooks/kapso', to: 'kapso_webhooks#create'
|
|
33
|
+
get '/webhooks/kapso', to: 'kapso_webhooks#verify' # For webhook verification
|
|
34
|
+
RUBY
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def show_readme
|
|
38
|
+
say <<~MESSAGE
|
|
39
|
+
|
|
40
|
+
KapsoClientRuby has been successfully installed!
|
|
41
|
+
|
|
42
|
+
Next steps:
|
|
43
|
+
1. Add your Kapso credentials to your environment variables:
|
|
44
|
+
- KAPSO_API_KEY
|
|
45
|
+
- KAPSO_PHONE_NUMBER_ID
|
|
46
|
+
- KAPSO_BUSINESS_ACCOUNT_ID
|
|
47
|
+
|
|
48
|
+
2. Review and customize the generated files:
|
|
49
|
+
- config/initializers/kapso_client_ruby.rb
|
|
50
|
+
- app/controllers/kapso_webhooks_controller.rb
|
|
51
|
+
- app/services/kapso_message_service.rb
|
|
52
|
+
|
|
53
|
+
3. Set up your webhook URL in the Kapso dashboard:
|
|
54
|
+
https://yourapp.com/webhooks/kapso
|
|
55
|
+
|
|
56
|
+
4. Test the integration:
|
|
57
|
+
rails runner "KapsoMessageService.new.send_test_message"
|
|
58
|
+
|
|
59
|
+
For more information, see: https://github.com/PabloB07/kapso-client-ruby
|
|
60
|
+
|
|
61
|
+
MESSAGE
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def application_name
|
|
67
|
+
if defined?(Rails) && Rails.application
|
|
68
|
+
Rails.application.class.name.split('::').first
|
|
69
|
+
else
|
|
70
|
+
'YourApp'
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
76
|
end
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
# Kapso API Configuration
|
|
2
|
-
# Add these to your actual .env file (don't commit API keys to version control)
|
|
3
|
-
|
|
4
|
-
# Required: Your Kapso API access token
|
|
5
|
-
KAPSO_API_KEY=your_api_key_here
|
|
6
|
-
|
|
7
|
-
# Required: Your WhatsApp Business phone number ID
|
|
8
|
-
KAPSO_PHONE_NUMBER_ID=your_phone_number_id_here
|
|
9
|
-
|
|
10
|
-
# Required: Your WhatsApp Business account ID
|
|
11
|
-
KAPSO_BUSINESS_ACCOUNT_ID=your_business_account_id_here
|
|
12
|
-
|
|
13
|
-
# Optional: API configuration
|
|
14
|
-
KAPSO_API_HOST=https://graph.facebook.com
|
|
15
|
-
KAPSO_API_VERSION=
|
|
16
|
-
KAPSO_TIMEOUT=30
|
|
17
|
-
|
|
18
|
-
# Optional: Debug and retry settings
|
|
19
|
-
KAPSO_DEBUG=false
|
|
20
|
-
KAPSO_RETRY_ON_FAILURE=true
|
|
1
|
+
# Kapso API Configuration
|
|
2
|
+
# Add these to your actual .env file (don't commit API keys to version control)
|
|
3
|
+
|
|
4
|
+
# Required: Your Kapso API access token
|
|
5
|
+
KAPSO_API_KEY=your_api_key_here
|
|
6
|
+
|
|
7
|
+
# Required: Your WhatsApp Business phone number ID
|
|
8
|
+
KAPSO_PHONE_NUMBER_ID=your_phone_number_id_here
|
|
9
|
+
|
|
10
|
+
# Required: Your WhatsApp Business account ID
|
|
11
|
+
KAPSO_BUSINESS_ACCOUNT_ID=your_business_account_id_here
|
|
12
|
+
|
|
13
|
+
# Optional: API configuration
|
|
14
|
+
KAPSO_API_HOST=https://graph.facebook.com
|
|
15
|
+
KAPSO_API_VERSION=v23.0
|
|
16
|
+
KAPSO_TIMEOUT=30
|
|
17
|
+
|
|
18
|
+
# Optional: Debug and retry settings
|
|
19
|
+
KAPSO_DEBUG=false
|
|
20
|
+
KAPSO_RETRY_ON_FAILURE=true
|
|
21
21
|
KAPSO_MAX_RETRIES=3
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# KapsoClientRuby configuration for Rails
|
|
4
|
-
KapsoClientRuby.configure do |config|
|
|
5
|
-
# API credentials - set these in your environment variables
|
|
6
|
-
config.api_key = ENV['KAPSO_API_KEY']
|
|
7
|
-
config.phone_number_id = ENV['KAPSO_PHONE_NUMBER_ID']
|
|
8
|
-
config.business_account_id = ENV['KAPSO_BUSINESS_ACCOUNT_ID']
|
|
9
|
-
|
|
10
|
-
# API configuration
|
|
11
|
-
config.api_host = ENV.fetch('KAPSO_API_HOST', 'https://graph.facebook.com')
|
|
12
|
-
config.api_version = ENV.fetch('KAPSO_API_VERSION', 'v18.0')
|
|
13
|
-
config.timeout = ENV.fetch('KAPSO_TIMEOUT', 30).to_i
|
|
14
|
-
|
|
15
|
-
# Development/Debug settings
|
|
16
|
-
config.debug = Rails.env.development? || ENV.fetch('KAPSO_DEBUG', 'false') == 'true'
|
|
17
|
-
config.logger = Rails.logger
|
|
18
|
-
|
|
19
|
-
# Retry configuration
|
|
20
|
-
config.retry_on_failure = ENV.fetch('KAPSO_RETRY_ON_FAILURE', 'true') == 'true'
|
|
21
|
-
config.max_retries = ENV.fetch('KAPSO_MAX_RETRIES', 3).to_i
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# Subscribe to Kapso events (optional)
|
|
25
|
-
# ActiveSupport::Notifications.subscribe('kapso.message_received') do |name, start, finish, id, payload|
|
|
26
|
-
# Rails.logger.info "Received WhatsApp message: #{payload[:message]['id']}"
|
|
27
|
-
# # Handle incoming message
|
|
28
|
-
# end
|
|
29
|
-
|
|
30
|
-
# ActiveSupport::Notifications.subscribe('kapso.message_status_updated') do |name, start, finish, id, payload|
|
|
31
|
-
# Rails.logger.info "Message status updated: #{payload[:status]['id']} -> #{payload[:status]['status']}"
|
|
32
|
-
# # Handle message status update
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# KapsoClientRuby configuration for Rails
|
|
4
|
+
KapsoClientRuby.configure do |config|
|
|
5
|
+
# API credentials - set these in your environment variables
|
|
6
|
+
config.api_key = ENV['KAPSO_API_KEY']
|
|
7
|
+
config.phone_number_id = ENV['KAPSO_PHONE_NUMBER_ID']
|
|
8
|
+
config.business_account_id = ENV['KAPSO_BUSINESS_ACCOUNT_ID']
|
|
9
|
+
|
|
10
|
+
# API configuration
|
|
11
|
+
config.api_host = ENV.fetch('KAPSO_API_HOST', 'https://graph.facebook.com')
|
|
12
|
+
config.api_version = ENV.fetch('KAPSO_API_VERSION', 'v18.0')
|
|
13
|
+
config.timeout = ENV.fetch('KAPSO_TIMEOUT', 30).to_i
|
|
14
|
+
|
|
15
|
+
# Development/Debug settings
|
|
16
|
+
config.debug = Rails.env.development? || ENV.fetch('KAPSO_DEBUG', 'false') == 'true'
|
|
17
|
+
config.logger = Rails.logger
|
|
18
|
+
|
|
19
|
+
# Retry configuration
|
|
20
|
+
config.retry_on_failure = ENV.fetch('KAPSO_RETRY_ON_FAILURE', 'true') == 'true'
|
|
21
|
+
config.max_retries = ENV.fetch('KAPSO_MAX_RETRIES', 3).to_i
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Subscribe to Kapso events (optional)
|
|
25
|
+
# ActiveSupport::Notifications.subscribe('kapso.message_received') do |name, start, finish, id, payload|
|
|
26
|
+
# Rails.logger.info "Received WhatsApp message: #{payload[:message]['id']}"
|
|
27
|
+
# # Handle incoming message
|
|
28
|
+
# end
|
|
29
|
+
|
|
30
|
+
# ActiveSupport::Notifications.subscribe('kapso.message_status_updated') do |name, start, finish, id, payload|
|
|
31
|
+
# Rails.logger.info "Message status updated: #{payload[:status]['id']} -> #{payload[:status]['status']}"
|
|
32
|
+
# # Handle message status update
|
|
33
33
|
# end
|
|
@@ -1,138 +1,138 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Example service class for sending WhatsApp messages in a Rails application
|
|
4
|
-
# This wraps the KapsoClientRuby functionality with Rails-specific features
|
|
5
|
-
class KapsoMessageService
|
|
6
|
-
include ActiveModel::Model
|
|
7
|
-
include ActiveModel::Attributes
|
|
8
|
-
|
|
9
|
-
# Initialize with optional custom client
|
|
10
|
-
def initialize(client: nil)
|
|
11
|
-
@kapso_service = KapsoClientRuby::Rails::Service.new(client)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# Send a welcome message to a new user
|
|
15
|
-
# @param user [User] The user to send the message to
|
|
16
|
-
# @return [Hash] API response
|
|
17
|
-
def send_welcome_message(user)
|
|
18
|
-
return unless user.phone_number.present?
|
|
19
|
-
|
|
20
|
-
@kapso_service.send_template_message(
|
|
21
|
-
to: user.phone_number,
|
|
22
|
-
template_name: 'welcome_message',
|
|
23
|
-
language: user.preferred_language || 'en',
|
|
24
|
-
components: [
|
|
25
|
-
{
|
|
26
|
-
type: 'body',
|
|
27
|
-
parameters: [
|
|
28
|
-
{ type: 'text', text: user.first_name || 'there' }
|
|
29
|
-
]
|
|
30
|
-
}
|
|
31
|
-
]
|
|
32
|
-
)
|
|
33
|
-
rescue KapsoClientRuby::Error => e
|
|
34
|
-
Rails.logger.error "Failed to send welcome message to user #{user.id}: #{e.message}"
|
|
35
|
-
# You might want to queue for retry or notify admins
|
|
36
|
-
nil
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# Send order confirmation
|
|
40
|
-
# @param order [Order] The order to confirm
|
|
41
|
-
# @return [Hash] API response
|
|
42
|
-
def send_order_confirmation(order)
|
|
43
|
-
user = order.user
|
|
44
|
-
return unless user.phone_number.present?
|
|
45
|
-
|
|
46
|
-
@kapso_service.send_template_message(
|
|
47
|
-
to: user.phone_number,
|
|
48
|
-
template_name: 'order_confirmation',
|
|
49
|
-
language: user.preferred_language || 'en',
|
|
50
|
-
components: [
|
|
51
|
-
{
|
|
52
|
-
type: 'body',
|
|
53
|
-
parameters: [
|
|
54
|
-
{ type: 'text', text: order.id.to_s },
|
|
55
|
-
{ type: 'currency', currency: order.currency, amount_1000: order.total_cents }
|
|
56
|
-
]
|
|
57
|
-
}
|
|
58
|
-
]
|
|
59
|
-
)
|
|
60
|
-
rescue KapsoClientRuby::Error => e
|
|
61
|
-
Rails.logger.error "Failed to send order confirmation for order #{order.id}: #{e.message}"
|
|
62
|
-
nil
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# Send a custom text message
|
|
66
|
-
# @param phone_number [String] Recipient's phone number
|
|
67
|
-
# @param message [String] The message text
|
|
68
|
-
# @return [Hash] API response
|
|
69
|
-
def send_text(phone_number:, message:)
|
|
70
|
-
@kapso_service.send_text_message(to: phone_number, text: message)
|
|
71
|
-
rescue KapsoClientRuby::Error => e
|
|
72
|
-
Rails.logger.error "Failed to send text message to #{phone_number}: #{e.message}"
|
|
73
|
-
nil
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# Send a document
|
|
77
|
-
# @param phone_number [String] Recipient's phone number
|
|
78
|
-
# @param document_url [String] URL of the document
|
|
79
|
-
# @param filename [String] Optional filename
|
|
80
|
-
# @param caption [String] Optional caption
|
|
81
|
-
# @return [Hash] API response
|
|
82
|
-
def send_document(phone_number:, document_url:, filename: nil, caption: nil)
|
|
83
|
-
@kapso_service.send_media_message(
|
|
84
|
-
to: phone_number,
|
|
85
|
-
media_type: 'document',
|
|
86
|
-
media_url: document_url,
|
|
87
|
-
filename: filename,
|
|
88
|
-
caption: caption
|
|
89
|
-
)
|
|
90
|
-
rescue KapsoClientRuby::Error => e
|
|
91
|
-
Rails.logger.error "Failed to send document to #{phone_number}: #{e.message}"
|
|
92
|
-
nil
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# Send test message (for development/testing)
|
|
96
|
-
def send_test_message
|
|
97
|
-
test_number = ENV['KAPSO_TEST_PHONE_NUMBER']
|
|
98
|
-
|
|
99
|
-
unless test_number
|
|
100
|
-
puts "Set KAPSO_TEST_PHONE_NUMBER environment variable to test messaging"
|
|
101
|
-
return
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
result = send_text(
|
|
105
|
-
phone_number: test_number,
|
|
106
|
-
message: "Hello from <%= application_name %>! This is a test message sent at #{Time.current}."
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
if result
|
|
110
|
-
puts "✅ Test message sent successfully! Message ID: #{result.dig('messages', 0, 'id')}"
|
|
111
|
-
else
|
|
112
|
-
puts "❌ Failed to send test message"
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
# Get message delivery status
|
|
117
|
-
# @param message_id [String] The message ID
|
|
118
|
-
# @return [Hash] Status information
|
|
119
|
-
def get_message_status(message_id)
|
|
120
|
-
@kapso_service.get_message_status(message_id)
|
|
121
|
-
rescue KapsoClientRuby::Error => e
|
|
122
|
-
Rails.logger.error "Failed to get message status for #{message_id}: #{e.message}"
|
|
123
|
-
nil
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# List available templates
|
|
127
|
-
# @return [Array] List of templates
|
|
128
|
-
def list_templates
|
|
129
|
-
@kapso_service.get_templates
|
|
130
|
-
rescue KapsoClientRuby::Error => e
|
|
131
|
-
Rails.logger.error "Failed to fetch templates: #{e.message}"
|
|
132
|
-
nil
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
private
|
|
136
|
-
|
|
137
|
-
attr_reader :kapso_service
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Example service class for sending WhatsApp messages in a Rails application
|
|
4
|
+
# This wraps the KapsoClientRuby functionality with Rails-specific features
|
|
5
|
+
class KapsoMessageService
|
|
6
|
+
include ActiveModel::Model
|
|
7
|
+
include ActiveModel::Attributes
|
|
8
|
+
|
|
9
|
+
# Initialize with optional custom client
|
|
10
|
+
def initialize(client: nil)
|
|
11
|
+
@kapso_service = KapsoClientRuby::Rails::Service.new(client)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Send a welcome message to a new user
|
|
15
|
+
# @param user [User] The user to send the message to
|
|
16
|
+
# @return [Hash] API response
|
|
17
|
+
def send_welcome_message(user)
|
|
18
|
+
return unless user.phone_number.present?
|
|
19
|
+
|
|
20
|
+
@kapso_service.send_template_message(
|
|
21
|
+
to: user.phone_number,
|
|
22
|
+
template_name: 'welcome_message',
|
|
23
|
+
language: user.preferred_language || 'en',
|
|
24
|
+
components: [
|
|
25
|
+
{
|
|
26
|
+
type: 'body',
|
|
27
|
+
parameters: [
|
|
28
|
+
{ type: 'text', text: user.first_name || 'there' }
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
)
|
|
33
|
+
rescue KapsoClientRuby::Error => e
|
|
34
|
+
Rails.logger.error "Failed to send welcome message to user #{user.id}: #{e.message}"
|
|
35
|
+
# You might want to queue for retry or notify admins
|
|
36
|
+
nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Send order confirmation
|
|
40
|
+
# @param order [Order] The order to confirm
|
|
41
|
+
# @return [Hash] API response
|
|
42
|
+
def send_order_confirmation(order)
|
|
43
|
+
user = order.user
|
|
44
|
+
return unless user.phone_number.present?
|
|
45
|
+
|
|
46
|
+
@kapso_service.send_template_message(
|
|
47
|
+
to: user.phone_number,
|
|
48
|
+
template_name: 'order_confirmation',
|
|
49
|
+
language: user.preferred_language || 'en',
|
|
50
|
+
components: [
|
|
51
|
+
{
|
|
52
|
+
type: 'body',
|
|
53
|
+
parameters: [
|
|
54
|
+
{ type: 'text', text: order.id.to_s },
|
|
55
|
+
{ type: 'currency', currency: order.currency, amount_1000: order.total_cents }
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
)
|
|
60
|
+
rescue KapsoClientRuby::Error => e
|
|
61
|
+
Rails.logger.error "Failed to send order confirmation for order #{order.id}: #{e.message}"
|
|
62
|
+
nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Send a custom text message
|
|
66
|
+
# @param phone_number [String] Recipient's phone number
|
|
67
|
+
# @param message [String] The message text
|
|
68
|
+
# @return [Hash] API response
|
|
69
|
+
def send_text(phone_number:, message:)
|
|
70
|
+
@kapso_service.send_text_message(to: phone_number, text: message)
|
|
71
|
+
rescue KapsoClientRuby::Error => e
|
|
72
|
+
Rails.logger.error "Failed to send text message to #{phone_number}: #{e.message}"
|
|
73
|
+
nil
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Send a document
|
|
77
|
+
# @param phone_number [String] Recipient's phone number
|
|
78
|
+
# @param document_url [String] URL of the document
|
|
79
|
+
# @param filename [String] Optional filename
|
|
80
|
+
# @param caption [String] Optional caption
|
|
81
|
+
# @return [Hash] API response
|
|
82
|
+
def send_document(phone_number:, document_url:, filename: nil, caption: nil)
|
|
83
|
+
@kapso_service.send_media_message(
|
|
84
|
+
to: phone_number,
|
|
85
|
+
media_type: 'document',
|
|
86
|
+
media_url: document_url,
|
|
87
|
+
filename: filename,
|
|
88
|
+
caption: caption
|
|
89
|
+
)
|
|
90
|
+
rescue KapsoClientRuby::Error => e
|
|
91
|
+
Rails.logger.error "Failed to send document to #{phone_number}: #{e.message}"
|
|
92
|
+
nil
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Send test message (for development/testing)
|
|
96
|
+
def send_test_message
|
|
97
|
+
test_number = ENV['KAPSO_TEST_PHONE_NUMBER']
|
|
98
|
+
|
|
99
|
+
unless test_number
|
|
100
|
+
puts "Set KAPSO_TEST_PHONE_NUMBER environment variable to test messaging"
|
|
101
|
+
return
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
result = send_text(
|
|
105
|
+
phone_number: test_number,
|
|
106
|
+
message: "Hello from <%= application_name %>! This is a test message sent at #{Time.current}."
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
if result
|
|
110
|
+
puts "✅ Test message sent successfully! Message ID: #{result.dig('messages', 0, 'id')}"
|
|
111
|
+
else
|
|
112
|
+
puts "❌ Failed to send test message"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Get message delivery status
|
|
117
|
+
# @param message_id [String] The message ID
|
|
118
|
+
# @return [Hash] Status information
|
|
119
|
+
def get_message_status(message_id)
|
|
120
|
+
@kapso_service.get_message_status(message_id)
|
|
121
|
+
rescue KapsoClientRuby::Error => e
|
|
122
|
+
Rails.logger.error "Failed to get message status for #{message_id}: #{e.message}"
|
|
123
|
+
nil
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# List available templates
|
|
127
|
+
# @return [Array] List of templates
|
|
128
|
+
def list_templates
|
|
129
|
+
@kapso_service.get_templates
|
|
130
|
+
rescue KapsoClientRuby::Error => e
|
|
131
|
+
Rails.logger.error "Failed to fetch templates: #{e.message}"
|
|
132
|
+
nil
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
private
|
|
136
|
+
|
|
137
|
+
attr_reader :kapso_service
|
|
138
138
|
end
|
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class KapsoWebhooksController < ApplicationController
|
|
4
|
-
# Skip CSRF token verification for webhook endpoints
|
|
5
|
-
skip_before_action :verify_authenticity_token
|
|
6
|
-
|
|
7
|
-
# Webhook verification endpoint (GET)
|
|
8
|
-
# WhatsApp sends a GET request to verify your webhook URL
|
|
9
|
-
def verify
|
|
10
|
-
challenge = params['hub.challenge']
|
|
11
|
-
verify_token = params['hub.verify_token']
|
|
12
|
-
|
|
13
|
-
# Set your verification token in environment variables
|
|
14
|
-
expected_token = ENV['KAPSO_WEBHOOK_VERIFY_TOKEN']
|
|
15
|
-
|
|
16
|
-
if verify_token == expected_token
|
|
17
|
-
render plain: challenge, status: :ok
|
|
18
|
-
else
|
|
19
|
-
render plain: 'Forbidden', status: :forbidden
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# Webhook payload endpoint (POST)
|
|
24
|
-
# WhatsApp sends webhook events here
|
|
25
|
-
def create
|
|
26
|
-
begin
|
|
27
|
-
# Verify webhook signature (optional but recommended)
|
|
28
|
-
verify_webhook_signature if ENV['KAPSO_WEBHOOK_SECRET'].present?
|
|
29
|
-
|
|
30
|
-
# Process the webhook using the Kapso Rails service
|
|
31
|
-
service = KapsoClientRuby::Rails::Service.new
|
|
32
|
-
result = service.process_webhook(webhook_params.to_h)
|
|
33
|
-
|
|
34
|
-
render json: { status: 'ok' }, status: :ok
|
|
35
|
-
rescue => e
|
|
36
|
-
Rails.logger.error "Webhook processing error: #{e.message}"
|
|
37
|
-
render json: { error: 'Internal server error' }, status: :internal_server_error
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
private
|
|
42
|
-
|
|
43
|
-
def webhook_params
|
|
44
|
-
params.permit!
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def verify_webhook_signature
|
|
48
|
-
signature = request.headers['X-Hub-Signature-256']
|
|
49
|
-
return unless signature
|
|
50
|
-
|
|
51
|
-
expected_signature = calculate_signature(request.raw_post)
|
|
52
|
-
|
|
53
|
-
unless Rack::Utils.secure_compare(signature, expected_signature)
|
|
54
|
-
raise 'Invalid webhook signature'
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def calculate_signature(payload)
|
|
59
|
-
secret = ENV['KAPSO_WEBHOOK_SECRET']
|
|
60
|
-
'sha256=' + OpenSSL::HMAC.hexdigest('sha256', secret, payload)
|
|
61
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class KapsoWebhooksController < ApplicationController
|
|
4
|
+
# Skip CSRF token verification for webhook endpoints
|
|
5
|
+
skip_before_action :verify_authenticity_token
|
|
6
|
+
|
|
7
|
+
# Webhook verification endpoint (GET)
|
|
8
|
+
# WhatsApp sends a GET request to verify your webhook URL
|
|
9
|
+
def verify
|
|
10
|
+
challenge = params['hub.challenge']
|
|
11
|
+
verify_token = params['hub.verify_token']
|
|
12
|
+
|
|
13
|
+
# Set your verification token in environment variables
|
|
14
|
+
expected_token = ENV['KAPSO_WEBHOOK_VERIFY_TOKEN']
|
|
15
|
+
|
|
16
|
+
if verify_token == expected_token
|
|
17
|
+
render plain: challenge, status: :ok
|
|
18
|
+
else
|
|
19
|
+
render plain: 'Forbidden', status: :forbidden
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Webhook payload endpoint (POST)
|
|
24
|
+
# WhatsApp sends webhook events here
|
|
25
|
+
def create
|
|
26
|
+
begin
|
|
27
|
+
# Verify webhook signature (optional but recommended)
|
|
28
|
+
verify_webhook_signature if ENV['KAPSO_WEBHOOK_SECRET'].present?
|
|
29
|
+
|
|
30
|
+
# Process the webhook using the Kapso Rails service
|
|
31
|
+
service = KapsoClientRuby::Rails::Service.new
|
|
32
|
+
result = service.process_webhook(webhook_params.to_h)
|
|
33
|
+
|
|
34
|
+
render json: { status: 'ok' }, status: :ok
|
|
35
|
+
rescue => e
|
|
36
|
+
Rails.logger.error "Webhook processing error: #{e.message}"
|
|
37
|
+
render json: { error: 'Internal server error' }, status: :internal_server_error
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def webhook_params
|
|
44
|
+
params.permit!
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def verify_webhook_signature
|
|
48
|
+
signature = request.headers['X-Hub-Signature-256']
|
|
49
|
+
return unless signature
|
|
50
|
+
|
|
51
|
+
expected_signature = calculate_signature(request.raw_post)
|
|
52
|
+
|
|
53
|
+
unless Rack::Utils.secure_compare(signature, expected_signature)
|
|
54
|
+
raise 'Invalid webhook signature'
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def calculate_signature(payload)
|
|
59
|
+
secret = ENV['KAPSO_WEBHOOK_SECRET']
|
|
60
|
+
'sha256=' + OpenSSL::HMAC.hexdigest('sha256', secret, payload)
|
|
61
|
+
end
|
|
62
62
|
end
|