kapso-client-ruby 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +478 -0
  6. data/README.md +1053 -734
  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 +388 -0
  18. data/examples/rails/models.rb +240 -0
  19. data/examples/rails/notifications_controller.rb +227 -0
  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 +76 -0
  25. data/lib/kapso_client_ruby/rails/generators/templates/env.erb +21 -0
  26. data/lib/kapso_client_ruby/rails/generators/templates/initializer.rb.erb +33 -0
  27. data/lib/kapso_client_ruby/rails/generators/templates/message_service.rb.erb +138 -0
  28. data/lib/kapso_client_ruby/rails/generators/templates/webhook_controller.rb.erb +62 -0
  29. data/lib/kapso_client_ruby/rails/railtie.rb +55 -0
  30. data/lib/kapso_client_ruby/rails/service.rb +189 -0
  31. data/lib/kapso_client_ruby/rails/tasks.rake +167 -0
  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 -68
  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 +24 -3
@@ -0,0 +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
76
+ end
@@ -0,0 +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=v23.0
16
+ KAPSO_TIMEOUT=30
17
+
18
+ # Optional: Debug and retry settings
19
+ KAPSO_DEBUG=false
20
+ KAPSO_RETRY_ON_FAILURE=true
21
+ KAPSO_MAX_RETRIES=3
@@ -0,0 +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
33
+ # end
@@ -0,0 +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
138
+ end
@@ -0,0 +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
62
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/railtie'
4
+
5
+ module KapsoClientRuby
6
+ module Rails
7
+ # Rails integration for KapsoClientRuby
8
+ class Railtie < ::Rails::Railtie
9
+ railtie_name :kapso_client_ruby
10
+
11
+ # Add kapso configuration to Rails application config
12
+ config.kapso = ActiveSupport::OrderedOptions.new
13
+
14
+ # Set default configuration values
15
+ config.before_configuration do |app|
16
+ app.config.kapso.api_key = nil
17
+ app.config.kapso.phone_number_id = nil
18
+ app.config.kapso.business_account_id = nil
19
+ app.config.kapso.api_host = 'https://graph.facebook.com'
20
+ app.config.kapso.api_version = 'v23.0'
21
+ app.config.kapso.timeout = 30
22
+ app.config.kapso.debug = false
23
+ app.config.kapso.logger = nil
24
+ app.config.kapso.retry_on_failure = true
25
+ app.config.kapso.max_retries = 3
26
+ end
27
+
28
+ # Initialize Kapso client after Rails application initialization
29
+ initializer 'kapso_client_ruby.configure' do |app|
30
+ KapsoClientRuby.configure do |config|
31
+ config.api_key = app.config.kapso.api_key || ENV['KAPSO_API_KEY']
32
+ config.phone_number_id = app.config.kapso.phone_number_id || ENV['KAPSO_PHONE_NUMBER_ID']
33
+ config.business_account_id = app.config.kapso.business_account_id || ENV['KAPSO_BUSINESS_ACCOUNT_ID']
34
+ config.api_host = app.config.kapso.api_host || ENV.fetch('KAPSO_API_HOST', 'https://graph.facebook.com')
35
+ config.api_version = app.config.kapso.api_version || ENV.fetch('KAPSO_API_VERSION', 'v23.0')
36
+ config.timeout = app.config.kapso.timeout || ENV.fetch('KAPSO_TIMEOUT', 30).to_i
37
+ config.debug = app.config.kapso.debug || ENV.fetch('KAPSO_DEBUG', 'false') == 'true'
38
+ config.logger = app.config.kapso.logger || ::Rails.logger
39
+ config.retry_on_failure = app.config.kapso.retry_on_failure
40
+ config.max_retries = app.config.kapso.max_retries || ENV.fetch('KAPSO_MAX_RETRIES', 3).to_i
41
+ end
42
+ end
43
+
44
+ # Add rake tasks
45
+ rake_tasks do
46
+ load 'kapso_client_ruby/rails/tasks.rake'
47
+ end
48
+
49
+ # Add generators
50
+ generators do
51
+ require 'kapso_client_ruby/rails/generators/install_generator'
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,189 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KapsoClientRuby
4
+ module Rails
5
+ # Service class for Rails integration with KapsoClientRuby
6
+ # Provides a convenient interface for Rails applications to interact with the Kapso API
7
+ class Service
8
+ include ActiveSupport::Configurable
9
+
10
+ # @return [KapsoClientRuby::Client] The configured Kapso client
11
+ attr_reader :client
12
+
13
+ def initialize(client = nil)
14
+ @client = client || KapsoClientRuby::Client.new
15
+ end
16
+
17
+ # Send a text message
18
+ # @param to [String] The recipient's phone number
19
+ # @param text [String] The message text
20
+ # @param options [Hash] Additional options
21
+ # @return [Hash] API response
22
+ def send_text_message(to:, text:, **options)
23
+ Rails.logger.info "Sending text message to #{to}: #{text.truncate(50)}"
24
+
25
+ result = client.messages.send_text(
26
+ to: to,
27
+ text: text,
28
+ **options
29
+ )
30
+
31
+ Rails.logger.info "Message sent successfully. ID: #{result.dig('messages', 0, 'id')}"
32
+ result
33
+ rescue KapsoClientRuby::Error => e
34
+ Rails.logger.error "Failed to send text message: #{e.message}"
35
+ raise
36
+ end
37
+
38
+ # Send a template message
39
+ # @param to [String] The recipient's phone number
40
+ # @param template_name [String] The template name
41
+ # @param language [String] The language code (default: 'en')
42
+ # @param components [Array] Template components
43
+ # @return [Hash] API response
44
+ def send_template_message(to:, template_name:, language: 'en', components: [])
45
+ Rails.logger.info "Sending template message '#{template_name}' to #{to}"
46
+
47
+ result = client.messages.send_template(
48
+ to: to,
49
+ name: template_name,
50
+ language: language,
51
+ components: components
52
+ )
53
+
54
+ Rails.logger.info "Template message sent successfully. ID: #{result.dig('messages', 0, 'id')}"
55
+ result
56
+ rescue KapsoClientRuby::Error => e
57
+ Rails.logger.error "Failed to send template message: #{e.message}"
58
+ raise
59
+ end
60
+
61
+ # Send a media message
62
+ # @param to [String] The recipient's phone number
63
+ # @param media_type [String] Type of media ('image', 'document', 'video', 'audio')
64
+ # @param media_url [String] URL of the media file
65
+ # @param options [Hash] Additional options
66
+ # @return [Hash] API response
67
+ def send_media_message(to:, media_type:, media_url:, **options)
68
+ Rails.logger.info "Sending #{media_type} message to #{to}: #{media_url}"
69
+
70
+ result = client.messages.send_media(
71
+ to: to,
72
+ type: media_type,
73
+ media_url: media_url,
74
+ **options
75
+ )
76
+
77
+ Rails.logger.info "Media message sent successfully. ID: #{result.dig('messages', 0, 'id')}"
78
+ result
79
+ rescue KapsoClientRuby::Error => e
80
+ Rails.logger.error "Failed to send media message: #{e.message}"
81
+ raise
82
+ end
83
+
84
+ # Upload media file
85
+ # @param file_path [String] Path to the media file
86
+ # @param media_type [String] Type of media
87
+ # @return [Hash] Upload response with media ID
88
+ def upload_media(file_path:, media_type:)
89
+ Rails.logger.info "Uploading media file: #{file_path}"
90
+
91
+ result = client.media.upload(
92
+ file_path: file_path,
93
+ type: media_type
94
+ )
95
+
96
+ Rails.logger.info "Media uploaded successfully. ID: #{result['id']}"
97
+ result
98
+ rescue KapsoClientRuby::Error => e
99
+ Rails.logger.error "Failed to upload media: #{e.message}"
100
+ raise
101
+ end
102
+
103
+ # Get message status
104
+ # @param message_id [String] The message ID
105
+ # @return [Hash] Message status
106
+ def get_message_status(message_id)
107
+ Rails.logger.debug "Getting status for message: #{message_id}"
108
+
109
+ result = client.messages.get_status(message_id)
110
+
111
+ Rails.logger.debug "Message status: #{result['status']}"
112
+ result
113
+ rescue KapsoClientRuby::Error => e
114
+ Rails.logger.error "Failed to get message status: #{e.message}"
115
+ raise
116
+ end
117
+
118
+ # Get templates
119
+ # @param options [Hash] Query options
120
+ # @return [Array] List of templates
121
+ def get_templates(**options)
122
+ Rails.logger.debug "Fetching templates with options: #{options}"
123
+
124
+ result = client.templates.list(**options)
125
+
126
+ Rails.logger.debug "Found #{result['data']&.length || 0} templates"
127
+ result
128
+ rescue KapsoClientRuby::Error => e
129
+ Rails.logger.error "Failed to fetch templates: #{e.message}"
130
+ raise
131
+ end
132
+
133
+ # Process incoming webhook
134
+ # @param webhook_data [Hash] The webhook payload
135
+ # @return [Hash] Processed webhook data
136
+ def process_webhook(webhook_data)
137
+ Rails.logger.info "Processing webhook: #{webhook_data}"
138
+
139
+ # Process webhook data based on type
140
+ entries = webhook_data['entry'] || []
141
+
142
+ entries.each do |entry|
143
+ changes = entry['changes'] || []
144
+
145
+ changes.each do |change|
146
+ case change['field']
147
+ when 'messages'
148
+ process_message_webhook(change['value'])
149
+ when 'message_template_status_update'
150
+ process_template_status_webhook(change['value'])
151
+ else
152
+ Rails.logger.warn "Unknown webhook field: #{change['field']}"
153
+ end
154
+ end
155
+ end
156
+
157
+ { status: 'processed' }
158
+ rescue => e
159
+ Rails.logger.error "Failed to process webhook: #{e.message}"
160
+ raise
161
+ end
162
+
163
+ private
164
+
165
+ def process_message_webhook(value)
166
+ messages = value['messages'] || []
167
+ statuses = value['statuses'] || []
168
+
169
+ messages.each do |message|
170
+ Rails.logger.info "Received message: #{message['id']} from #{message['from']}"
171
+ # Trigger Rails callback or event
172
+ ActiveSupport::Notifications.instrument('kapso.message_received', message: message)
173
+ end
174
+
175
+ statuses.each do |status|
176
+ Rails.logger.info "Message status update: #{status['id']} -> #{status['status']}"
177
+ # Trigger Rails callback or event
178
+ ActiveSupport::Notifications.instrument('kapso.message_status_updated', status: status)
179
+ end
180
+ end
181
+
182
+ def process_template_status_webhook(value)
183
+ Rails.logger.info "Template status update: #{value}"
184
+ # Trigger Rails callback or event
185
+ ActiveSupport::Notifications.instrument('kapso.template_status_updated', template_status: value)
186
+ end
187
+ end
188
+ end
189
+ end