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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +81 -81
  3. data/CHANGELOG.md +262 -91
  4. data/Gemfile +20 -20
  5. data/RAILS_INTEGRATION.md +477 -477
  6. data/README.md +1053 -752
  7. data/Rakefile +40 -40
  8. data/TEMPLATE_TOOLS_GUIDE.md +120 -120
  9. data/WHATSAPP_24_HOUR_GUIDE.md +133 -133
  10. data/examples/advanced_features.rb +352 -349
  11. data/examples/advanced_messaging.rb +241 -0
  12. data/examples/basic_messaging.rb +139 -136
  13. data/examples/enhanced_interactive.rb +400 -0
  14. data/examples/flows_usage.rb +307 -0
  15. data/examples/interactive_messages.rb +343 -0
  16. data/examples/media_management.rb +256 -253
  17. data/examples/rails/jobs.rb +387 -387
  18. data/examples/rails/models.rb +239 -239
  19. data/examples/rails/notifications_controller.rb +226 -226
  20. data/examples/template_management.rb +393 -390
  21. data/kapso-ruby-logo.jpg +0 -0
  22. data/lib/kapso_client_ruby/client.rb +321 -316
  23. data/lib/kapso_client_ruby/errors.rb +348 -329
  24. data/lib/kapso_client_ruby/rails/generators/install_generator.rb +75 -75
  25. data/lib/kapso_client_ruby/rails/generators/templates/env.erb +20 -20
  26. data/lib/kapso_client_ruby/rails/generators/templates/initializer.rb.erb +32 -32
  27. data/lib/kapso_client_ruby/rails/generators/templates/message_service.rb.erb +137 -137
  28. data/lib/kapso_client_ruby/rails/generators/templates/webhook_controller.rb.erb +61 -61
  29. data/lib/kapso_client_ruby/rails/railtie.rb +54 -54
  30. data/lib/kapso_client_ruby/rails/service.rb +188 -188
  31. data/lib/kapso_client_ruby/rails/tasks.rake +166 -166
  32. data/lib/kapso_client_ruby/resources/calls.rb +172 -172
  33. data/lib/kapso_client_ruby/resources/contacts.rb +190 -190
  34. data/lib/kapso_client_ruby/resources/conversations.rb +103 -103
  35. data/lib/kapso_client_ruby/resources/flows.rb +382 -0
  36. data/lib/kapso_client_ruby/resources/media.rb +205 -205
  37. data/lib/kapso_client_ruby/resources/messages.rb +760 -380
  38. data/lib/kapso_client_ruby/resources/phone_numbers.rb +85 -85
  39. data/lib/kapso_client_ruby/resources/templates.rb +283 -283
  40. data/lib/kapso_client_ruby/types.rb +348 -262
  41. data/lib/kapso_client_ruby/version.rb +5 -5
  42. data/lib/kapso_client_ruby.rb +75 -74
  43. data/scripts/.env.example +17 -17
  44. data/scripts/kapso_template_finder.rb +91 -91
  45. data/scripts/sdk_setup.rb +404 -404
  46. data/scripts/test.rb +60 -60
  47. 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=v18.0
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