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.
- checksums.yaml +4 -4
- data/.rubocop.yml +81 -81
- data/CHANGELOG.md +262 -91
- data/Gemfile +20 -20
- data/RAILS_INTEGRATION.md +478 -0
- data/README.md +1053 -734
- 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 +388 -0
- data/examples/rails/models.rb +240 -0
- data/examples/rails/notifications_controller.rb +227 -0
- 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 +76 -0
- data/lib/kapso_client_ruby/rails/generators/templates/env.erb +21 -0
- data/lib/kapso_client_ruby/rails/generators/templates/initializer.rb.erb +33 -0
- data/lib/kapso_client_ruby/rails/generators/templates/message_service.rb.erb +138 -0
- data/lib/kapso_client_ruby/rails/generators/templates/webhook_controller.rb.erb +62 -0
- data/lib/kapso_client_ruby/rails/railtie.rb +55 -0
- data/lib/kapso_client_ruby/rails/service.rb +189 -0
- data/lib/kapso_client_ruby/rails/tasks.rake +167 -0
- 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 -68
- 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 +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
|