whatsapp-cloud-api-ruby 1.0.0
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 +7 -0
- data/.rubocop.yml +82 -0
- data/CHANGELOG.md +92 -0
- data/Gemfile +21 -0
- data/README.md +735 -0
- data/Rakefile +41 -0
- data/TEMPLATE_TOOLS_GUIDE.md +121 -0
- data/WHATSAPP_24_HOUR_GUIDE.md +134 -0
- data/examples/advanced_features.rb +350 -0
- data/examples/basic_messaging.rb +137 -0
- data/examples/media_management.rb +254 -0
- data/examples/template_management.rb +391 -0
- data/lib/whatsapp_cloud_api/client.rb +317 -0
- data/lib/whatsapp_cloud_api/errors.rb +330 -0
- data/lib/whatsapp_cloud_api/resources/calls.rb +173 -0
- data/lib/whatsapp_cloud_api/resources/contacts.rb +191 -0
- data/lib/whatsapp_cloud_api/resources/conversations.rb +104 -0
- data/lib/whatsapp_cloud_api/resources/media.rb +206 -0
- data/lib/whatsapp_cloud_api/resources/messages.rb +381 -0
- data/lib/whatsapp_cloud_api/resources/phone_numbers.rb +86 -0
- data/lib/whatsapp_cloud_api/resources/templates.rb +284 -0
- data/lib/whatsapp_cloud_api/types.rb +263 -0
- data/lib/whatsapp_cloud_api/version.rb +5 -0
- data/lib/whatsapp_cloud_api.rb +69 -0
- data/scripts/.env.example +18 -0
- data/scripts/kapso_template_finder.rb +91 -0
- data/scripts/sdk_setup.rb +405 -0
- data/scripts/test.rb +60 -0
- metadata +254 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
# Kapso Proxy API
|
2
|
+
KAPSO_API_KEY=your_kapso_api_key_here
|
3
|
+
PHONE_NUMBER_ID=your_phone_number_id_here
|
4
|
+
WHATSAPP_BASE_URL=https://app.kapso.ai/api/meta
|
5
|
+
|
6
|
+
# Business Account ID (required for template management)
|
7
|
+
# Find this in your Kapso dashboard under WhatsApp Business section
|
8
|
+
BUSINESS_ACCOUNT_ID=your_business_account_id_here
|
9
|
+
|
10
|
+
# Optional: Set API version
|
11
|
+
# WHATSAPP_API_VERSION=v24.0
|
12
|
+
|
13
|
+
# Optional: Enable debug mode
|
14
|
+
# WHATSAPP_DEBUG=true
|
15
|
+
|
16
|
+
# Optional: Set timeouts (in seconds)
|
17
|
+
# WHATSAPP_TIMEOUT=30
|
18
|
+
# WHATSAPP_OPEN_TIMEOUT=10
|
@@ -0,0 +1,91 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'dotenv/load' rescue nil
|
5
|
+
require_relative '../lib/whatsapp_cloud_api'
|
6
|
+
|
7
|
+
puts "๐ Kapso Template Finder"
|
8
|
+
puts "=" * 30
|
9
|
+
|
10
|
+
kapso_api_key = ENV['KAPSO_API_KEY']
|
11
|
+
phone_number_id = ENV['PHONE_NUMBER_ID']
|
12
|
+
business_account_id = ENV['BUSINESS_ACCOUNT_ID']
|
13
|
+
|
14
|
+
unless kapso_api_key && phone_number_id
|
15
|
+
puts "โ Missing credentials. Run: ruby sdk_test.rb"
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
|
19
|
+
client = WhatsAppCloudApi::Client.new(
|
20
|
+
kapso_api_key: kapso_api_key,
|
21
|
+
base_url: ENV['WHATSAPP_BASE_URL'] || 'https://app.kapso.ai/api/meta'
|
22
|
+
)
|
23
|
+
|
24
|
+
puts "Phone: #{phone_number_id}"
|
25
|
+
puts "Business Account: #{business_account_id || 'Not set'}"
|
26
|
+
|
27
|
+
print "Destination (+56912345678): "
|
28
|
+
to_number = gets.chomp
|
29
|
+
to_number = "+56912345678" if to_number.empty?
|
30
|
+
|
31
|
+
puts "\n๐ Finding Templates..."
|
32
|
+
found_templates = []
|
33
|
+
|
34
|
+
# Try Business Account if available
|
35
|
+
if business_account_id
|
36
|
+
puts "Checking Business Account..."
|
37
|
+
begin
|
38
|
+
response = client.templates.list(business_account_id: business_account_id)
|
39
|
+
if response.data && response.data.any?
|
40
|
+
response.data.each do |template|
|
41
|
+
found_templates << {
|
42
|
+
name: template.name,
|
43
|
+
language: template.language,
|
44
|
+
status: template.status
|
45
|
+
}
|
46
|
+
puts "โ
#{template.name} (#{template.language}) - #{template.status}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
rescue => e
|
50
|
+
puts "โ Error: #{e.message}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Test common names if none found
|
55
|
+
if found_templates.empty?
|
56
|
+
puts "Testing common template names..."
|
57
|
+
["hello_world", "welcome_message"].each do |name|
|
58
|
+
print "Testing #{name}... "
|
59
|
+
begin
|
60
|
+
client.messages.send_template(
|
61
|
+
phone_number_id: phone_number_id,
|
62
|
+
to: to_number,
|
63
|
+
name: name,
|
64
|
+
language: "en_US"
|
65
|
+
)
|
66
|
+
puts "โ
WORKS"
|
67
|
+
found_templates << { name: name, language: "en_US", status: "APPROVED" }
|
68
|
+
rescue => e
|
69
|
+
puts "โ Not found" if e.message.include?("does not exist")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
puts "\n=" * 30
|
75
|
+
puts "๐ RESULTS"
|
76
|
+
|
77
|
+
if found_templates.any?
|
78
|
+
puts "Found #{found_templates.length} template(s):"
|
79
|
+
found_templates.each do |t|
|
80
|
+
puts "\nโข #{t[:name]} (#{t[:language]})"
|
81
|
+
puts " Status: #{t[:status]}"
|
82
|
+
end
|
83
|
+
puts "\n๐ฏ Templates work 24/7 - no time limits!"
|
84
|
+
else
|
85
|
+
puts "No templates found"
|
86
|
+
puts "\nNext steps:"
|
87
|
+
puts "1. Add BUSINESS_ACCOUNT_ID to .env"
|
88
|
+
puts "2. Create templates in Kapso dashboard"
|
89
|
+
end
|
90
|
+
|
91
|
+
puts "\n๐ก Templates solve the 24-hour problem!"
|
@@ -0,0 +1,405 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative '../lib/whatsapp_cloud_api'
|
5
|
+
|
6
|
+
puts "=== Kapso.ai and WhatsApp Cloud API Ruby SDK Setup ==="
|
7
|
+
puts
|
8
|
+
|
9
|
+
# Helper method for safe input
|
10
|
+
def get_input(prompt, required: false, mask: false)
|
11
|
+
loop do
|
12
|
+
print prompt
|
13
|
+
if mask
|
14
|
+
# For sensitive input, use a simple masking approach
|
15
|
+
begin
|
16
|
+
system "stty -echo" if STDIN.tty?
|
17
|
+
input = gets.chomp
|
18
|
+
ensure
|
19
|
+
system "stty echo" if STDIN.tty?
|
20
|
+
puts # New line after hidden input
|
21
|
+
end
|
22
|
+
else
|
23
|
+
input = gets.chomp
|
24
|
+
end
|
25
|
+
|
26
|
+
if required && input.strip.empty?
|
27
|
+
puts "โ This field is required. Please try again."
|
28
|
+
next
|
29
|
+
end
|
30
|
+
|
31
|
+
return input.strip
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Interactive Environment Setup
|
36
|
+
puts "๐ง WhatsApp Cloud API Configuration"
|
37
|
+
puts "-" * 40
|
38
|
+
puts "Please provide your API credentials (leave empty for test mode):"
|
39
|
+
puts
|
40
|
+
|
41
|
+
# Get Phone Number ID first (common to all)
|
42
|
+
phone_number_id = get_input("๐ฑ Phone Number ID (or press Enter for test mode): ")
|
43
|
+
|
44
|
+
if phone_number_id.empty?
|
45
|
+
# Test mode
|
46
|
+
puts "\n๐งช Test Mode - Using mock credentials"
|
47
|
+
ENV['WHATSAPP_ACCESS_TOKEN'] = 'test_token_12345'
|
48
|
+
ENV['PHONE_NUMBER_ID'] = 'test_phone_id_12345'
|
49
|
+
test_mode = true
|
50
|
+
puts "โ
Test credentials configured"
|
51
|
+
else
|
52
|
+
# Real credentials
|
53
|
+
ENV['PHONE_NUMBER_ID'] = phone_number_id
|
54
|
+
test_mode = false
|
55
|
+
|
56
|
+
puts "\nChoose your API provider:"
|
57
|
+
puts "๐ฑ Meta WhatsApp Business API (get token from: https://developers.facebook.com/apps)"
|
58
|
+
puts "๐ Kapso Proxy API (get key from: https://app.kapso.ai)"
|
59
|
+
puts
|
60
|
+
|
61
|
+
# Try to get access token first
|
62
|
+
access_token = get_input("๐ WhatsApp Access Token (or press Enter to use Kapso): ", mask: true)
|
63
|
+
|
64
|
+
if access_token.empty?
|
65
|
+
# Use Kapso API
|
66
|
+
kapso_api_key = get_input("๐ Kapso API Key: ", required: true, mask: true)
|
67
|
+
ENV['KAPSO_API_KEY'] = kapso_api_key
|
68
|
+
puts "โ
Kapso API credentials configured"
|
69
|
+
else
|
70
|
+
# Use Meta API
|
71
|
+
ENV['WHATSAPP_ACCESS_TOKEN'] = access_token
|
72
|
+
puts "โ
Meta API credentials configured"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
puts
|
77
|
+
puts "Current Configuration:"
|
78
|
+
if ENV['WHATSAPP_ACCESS_TOKEN']
|
79
|
+
puts " Access Token: ***#{ENV['WHATSAPP_ACCESS_TOKEN'][-4..-1]}"
|
80
|
+
elsif ENV['KAPSO_API_KEY']
|
81
|
+
puts " Kapso API Key: ***#{ENV['KAPSO_API_KEY'][-4..-1]}"
|
82
|
+
else
|
83
|
+
puts " Kapso API Key: Not set"
|
84
|
+
end
|
85
|
+
puts " Phone Number ID: #{ENV['PHONE_NUMBER_ID']}"
|
86
|
+
puts
|
87
|
+
|
88
|
+
test_real_api = false
|
89
|
+
if !test_mode # Only ask for real API test if not in test mode
|
90
|
+
puts "โ ๏ธ Real API Test Warning:"
|
91
|
+
puts " This will make actual API calls and may incur charges"
|
92
|
+
puts " Make sure your credentials are valid and you have proper permissions"
|
93
|
+
|
94
|
+
confirmation = get_input("Do you want to test with real API calls? (y/N): ")
|
95
|
+
test_real_api = confirmation.downcase == 'y' || confirmation.downcase == 'yes'
|
96
|
+
else
|
97
|
+
puts "โน๏ธ Test mode selected - skipping real API calls"
|
98
|
+
end
|
99
|
+
|
100
|
+
puts
|
101
|
+
|
102
|
+
# Test 1: Configuration and Client Initialization
|
103
|
+
puts "1. Testing Client Initialization"
|
104
|
+
puts "-" * 40
|
105
|
+
|
106
|
+
begin
|
107
|
+
# Initialize client based on configured environment
|
108
|
+
if ENV['KAPSO_API_KEY']
|
109
|
+
client = WhatsAppCloudApi::Client.new(
|
110
|
+
kapso_api_key: ENV['KAPSO_API_KEY'],
|
111
|
+
base_url: 'https://app.kapso.ai/api/meta',
|
112
|
+
debug: true
|
113
|
+
)
|
114
|
+
puts "โ
Kapso client initialized"
|
115
|
+
puts " Kapso proxy: #{client.kapso_proxy?}"
|
116
|
+
else
|
117
|
+
client = WhatsAppCloudApi::Client.new(
|
118
|
+
access_token: ENV['WHATSAPP_ACCESS_TOKEN'],
|
119
|
+
debug: true
|
120
|
+
)
|
121
|
+
puts "โ
Meta API client initialized"
|
122
|
+
puts " Kapso proxy: #{client.kapso_proxy?}"
|
123
|
+
end
|
124
|
+
|
125
|
+
puts " Debug mode: #{client.debug}"
|
126
|
+
|
127
|
+
rescue => e
|
128
|
+
puts "โ Client initialization failed: #{e.message}"
|
129
|
+
end
|
130
|
+
|
131
|
+
puts
|
132
|
+
|
133
|
+
# Test 2: Resource Access
|
134
|
+
puts "2. Testing Resource Access"
|
135
|
+
puts "-" * 40
|
136
|
+
|
137
|
+
begin
|
138
|
+
client = WhatsAppCloudApi::Client.new(access_token: 'test_token')
|
139
|
+
|
140
|
+
# Test all resource accessors
|
141
|
+
resources = {
|
142
|
+
'Messages' => client.messages,
|
143
|
+
'Media' => client.media,
|
144
|
+
'Templates' => client.templates,
|
145
|
+
'Phone Numbers' => client.phone_numbers,
|
146
|
+
'Calls' => client.calls,
|
147
|
+
'Conversations' => client.conversations,
|
148
|
+
'Contacts' => client.contacts
|
149
|
+
}
|
150
|
+
|
151
|
+
resources.each do |name, resource|
|
152
|
+
if resource
|
153
|
+
puts "โ
#{name} resource: #{resource.class}"
|
154
|
+
else
|
155
|
+
puts "โ #{name} resource: nil"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
rescue => e
|
160
|
+
puts "โ Resource access failed: #{e.message}"
|
161
|
+
end
|
162
|
+
|
163
|
+
puts
|
164
|
+
|
165
|
+
# Test 3: Configuration System
|
166
|
+
puts "3. Testing Configuration System"
|
167
|
+
puts "-" * 40
|
168
|
+
|
169
|
+
begin
|
170
|
+
# Test global configuration
|
171
|
+
WhatsAppCloudApi.configure do |config|
|
172
|
+
config.debug = true
|
173
|
+
config.timeout = 45
|
174
|
+
config.access_token = 'global_test_token'
|
175
|
+
end
|
176
|
+
|
177
|
+
puts "โ
Global configuration set"
|
178
|
+
puts " Debug: #{WhatsAppCloudApi.configuration.debug}"
|
179
|
+
puts " Timeout: #{WhatsAppCloudApi.configuration.timeout}"
|
180
|
+
puts " Access token present: #{!WhatsAppCloudApi.configuration.access_token.nil?}"
|
181
|
+
|
182
|
+
rescue => e
|
183
|
+
puts "โ Configuration failed: #{e.message}"
|
184
|
+
end
|
185
|
+
|
186
|
+
puts
|
187
|
+
|
188
|
+
# Test 4: Error Handling System
|
189
|
+
puts "4. Testing Error Handling System"
|
190
|
+
puts "-" * 40
|
191
|
+
|
192
|
+
begin
|
193
|
+
# Test creating different error types
|
194
|
+
rate_limit_error = WhatsAppCloudApi::Errors::GraphApiError.new(
|
195
|
+
message: 'Rate limit exceeded',
|
196
|
+
code: 4,
|
197
|
+
http_status: 429,
|
198
|
+
retry_after: 30
|
199
|
+
)
|
200
|
+
|
201
|
+
puts "โ
Rate limit error created"
|
202
|
+
puts " Category: #{rate_limit_error.category}"
|
203
|
+
puts " Rate limited?: #{rate_limit_error.rate_limit?}"
|
204
|
+
puts " Retry after: #{rate_limit_error.retry_after}s"
|
205
|
+
puts " Retry hint: #{rate_limit_error.retry_hint}"
|
206
|
+
|
207
|
+
auth_error = WhatsAppCloudApi::Errors::GraphApiError.new(
|
208
|
+
message: 'Invalid access token',
|
209
|
+
code: 190,
|
210
|
+
http_status: 401
|
211
|
+
)
|
212
|
+
|
213
|
+
puts "โ
Auth error created"
|
214
|
+
puts " Category: #{auth_error.category}"
|
215
|
+
puts " Temporary?: #{auth_error.temporary?}"
|
216
|
+
puts " Retry hint: #{auth_error.retry_hint}"
|
217
|
+
|
218
|
+
rescue => e
|
219
|
+
puts "โ Error handling test failed: #{e.message}"
|
220
|
+
end
|
221
|
+
|
222
|
+
puts
|
223
|
+
|
224
|
+
# Test 5: Payload Building (without API calls)
|
225
|
+
puts "5. Testing Message Payload Building"
|
226
|
+
puts "-" * 40
|
227
|
+
|
228
|
+
begin
|
229
|
+
# Use the configured client
|
230
|
+
messages = client.messages
|
231
|
+
|
232
|
+
# Test payload building (this is internal, so we'll simulate)
|
233
|
+
puts "โ
Messages resource ready"
|
234
|
+
puts " Available methods: send_text, send_image, send_template, etc."
|
235
|
+
|
236
|
+
# Test media types validation
|
237
|
+
media_types = WhatsAppCloudApi::Types::MEDIA_TYPES
|
238
|
+
puts "โ
Media types supported: #{media_types.join(', ')}"
|
239
|
+
|
240
|
+
# Test template statuses
|
241
|
+
template_statuses = WhatsAppCloudApi::Types::TEMPLATE_STATUSES
|
242
|
+
puts "โ
Template statuses: #{template_statuses.join(', ')}"
|
243
|
+
|
244
|
+
rescue => e
|
245
|
+
puts "โ Payload building test failed: #{e.message}"
|
246
|
+
end
|
247
|
+
|
248
|
+
puts
|
249
|
+
|
250
|
+
# Test 6: Logger System
|
251
|
+
puts "6. Testing Logger System"
|
252
|
+
puts "-" * 40
|
253
|
+
|
254
|
+
begin
|
255
|
+
logger = WhatsAppCloudApi.logger
|
256
|
+
puts "โ
Logger accessible"
|
257
|
+
puts " Logger class: #{logger.class}"
|
258
|
+
|
259
|
+
# Test logging (will show in console if debug enabled)
|
260
|
+
WhatsAppCloudApi.logger.info("SDK test completed successfully!")
|
261
|
+
|
262
|
+
rescue => e
|
263
|
+
puts "โ Logger test failed: #{e.message}"
|
264
|
+
end
|
265
|
+
|
266
|
+
puts
|
267
|
+
|
268
|
+
# Test 7: Real API Test (if requested)
|
269
|
+
if test_real_api
|
270
|
+
puts "7. Testing Real API Calls"
|
271
|
+
puts "-" * 40
|
272
|
+
|
273
|
+
begin
|
274
|
+
# Use the configured client from Test 1
|
275
|
+
phone_number_id = ENV['PHONE_NUMBER_ID']
|
276
|
+
|
277
|
+
if phone_number_id.nil? || phone_number_id.empty?
|
278
|
+
puts "โ Phone Number ID not configured"
|
279
|
+
else
|
280
|
+
puts "๐ฑ Enter the destination WhatsApp number:"
|
281
|
+
puts " โข Must include country code (e.g., +1234567890)"
|
282
|
+
puts " โข No spaces or special characters except +"
|
283
|
+
puts " โข Example: +56912345678"
|
284
|
+
puts
|
285
|
+
|
286
|
+
to_number = nil
|
287
|
+
loop do
|
288
|
+
to_number = get_input("Destination phone number: ", required: true)
|
289
|
+
|
290
|
+
# Basic phone number validation
|
291
|
+
if to_number.match(/^\+\d{10,15}$/)
|
292
|
+
break
|
293
|
+
else
|
294
|
+
puts "โ Invalid format. Please use format: +[country_code][number] (10-15 digits total)"
|
295
|
+
puts " Example: +56912345678"
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
puts "\n๐ฑ Sending test message to #{to_number}..."
|
300
|
+
|
301
|
+
response = client.messages.send_text(
|
302
|
+
phone_number_id: phone_number_id,
|
303
|
+
to: to_number,
|
304
|
+
body: "๐ Test message from WhatsApp Cloud API Ruby SDK! Time: #{Time.now}"
|
305
|
+
)
|
306
|
+
|
307
|
+
puts "โ
Message sent successfully!"
|
308
|
+
puts " Message ID: #{response.messages.first.id}"
|
309
|
+
puts " Contact WA ID: #{response.contacts.first.wa_id}"
|
310
|
+
puts " Message Status: #{response.messages.first.message_status}"
|
311
|
+
end
|
312
|
+
|
313
|
+
rescue WhatsAppCloudApi::Errors::GraphApiError => e
|
314
|
+
puts "โ API Error: #{e.message}"
|
315
|
+
puts " Category: #{e.category}"
|
316
|
+
puts " HTTP Status: #{e.http_status}"
|
317
|
+
puts " Error Code: #{e.code}"
|
318
|
+
puts " Retry Action: #{e.retry_hint}"
|
319
|
+
|
320
|
+
if e.rate_limit?
|
321
|
+
puts " โณ Rate limited! Retry after: #{e.retry_after}s"
|
322
|
+
end
|
323
|
+
|
324
|
+
rescue => e
|
325
|
+
puts "โ Unexpected error: #{e.message}"
|
326
|
+
puts " Class: #{e.class}"
|
327
|
+
end
|
328
|
+
|
329
|
+
puts
|
330
|
+
end
|
331
|
+
|
332
|
+
puts "=== Test Summary ==="
|
333
|
+
puts "โ
WhatsApp Cloud API Ruby SDK is working correctly!"
|
334
|
+
|
335
|
+
if test_real_api
|
336
|
+
puts "๐ Real API test completed"
|
337
|
+
else
|
338
|
+
puts "๐งช Mock tests completed successfully"
|
339
|
+
puts
|
340
|
+
puts "๐ก To test real API calls:"
|
341
|
+
puts " - Run this script again and choose option 1 or 2"
|
342
|
+
puts " - Provide your real WhatsApp Business API credentials"
|
343
|
+
puts " - Answer 'y' when asked to test real API calls"
|
344
|
+
end
|
345
|
+
|
346
|
+
puts
|
347
|
+
puts "๐ง Configuration used:"
|
348
|
+
if ENV['WHATSAPP_ACCESS_TOKEN']
|
349
|
+
puts " Access Token: Configured"
|
350
|
+
elsif ENV['KAPSO_API_KEY']
|
351
|
+
puts " Kapso API Key: Configured"
|
352
|
+
else
|
353
|
+
puts " Kapso API Key: Not set"
|
354
|
+
end
|
355
|
+
puts " Phone Number ID: #{ENV['PHONE_NUMBER_ID'] || 'Not set'}"
|
356
|
+
puts
|
357
|
+
|
358
|
+
# Create .env file with configured credentials
|
359
|
+
if !test_mode && (ENV['WHATSAPP_ACCESS_TOKEN'] || ENV['KAPSO_API_KEY'])
|
360
|
+
puts "๐พ Creating .env file for production use..."
|
361
|
+
|
362
|
+
env_content = []
|
363
|
+
env_content << "# WhatsApp Cloud API Configuration"
|
364
|
+
env_content << "# Generated by WhatsApp Cloud API Ruby SDK Test"
|
365
|
+
env_content << "# #{Time.now}"
|
366
|
+
env_content << ""
|
367
|
+
|
368
|
+
if ENV['WHATSAPP_ACCESS_TOKEN']
|
369
|
+
env_content << "# Meta WhatsApp Business API"
|
370
|
+
env_content << "WHATSAPP_ACCESS_TOKEN=#{ENV['WHATSAPP_ACCESS_TOKEN']}"
|
371
|
+
env_content << "PHONE_NUMBER_ID=#{ENV['PHONE_NUMBER_ID']}"
|
372
|
+
env_content << ""
|
373
|
+
env_content << "# Optional: Set base URL for custom endpoints"
|
374
|
+
env_content << "# WHATSAPP_BASE_URL=https://graph.facebook.com"
|
375
|
+
env_content << "# WHATSAPP_API_VERSION=v24.0"
|
376
|
+
end
|
377
|
+
|
378
|
+
if ENV['KAPSO_API_KEY']
|
379
|
+
env_content << "# Kapso Proxy API"
|
380
|
+
env_content << "KAPSO_API_KEY=#{ENV['KAPSO_API_KEY']}"
|
381
|
+
env_content << "PHONE_NUMBER_ID=#{ENV['PHONE_NUMBER_ID']}"
|
382
|
+
env_content << "WHATSAPP_BASE_URL=https://app.kapso.ai/api/meta"
|
383
|
+
env_content << ""
|
384
|
+
env_content << "# Optional: Set API version"
|
385
|
+
env_content << "# WHATSAPP_API_VERSION=v24.0"
|
386
|
+
end
|
387
|
+
|
388
|
+
env_content << ""
|
389
|
+
env_content << "# Optional: Enable debug mode"
|
390
|
+
env_content << "# WHATSAPP_DEBUG=true"
|
391
|
+
env_content << ""
|
392
|
+
env_content << "# Optional: Set timeouts (in seconds)"
|
393
|
+
env_content << "# WHATSAPP_TIMEOUT=30"
|
394
|
+
env_content << "# WHATSAPP_OPEN_TIMEOUT=10"
|
395
|
+
|
396
|
+
File.write('.env', env_content.join("\n"))
|
397
|
+
|
398
|
+
puts "โ
.env file created successfully!"
|
399
|
+
puts " You can now use: require 'dotenv/load' in your Ruby applications"
|
400
|
+
puts " Or set these environment variables in your deployment environment"
|
401
|
+
puts
|
402
|
+
end
|
403
|
+
|
404
|
+
puts "๐ See examples/ directory for more usage examples"
|
405
|
+
puts "๐ See README.md for full documentation"
|
data/scripts/test.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'dotenv/load' rescue nil
|
5
|
+
require_relative '../lib/whatsapp_cloud_api'
|
6
|
+
|
7
|
+
puts "๐ Kapso API Quick Test"
|
8
|
+
|
9
|
+
# Get credentials
|
10
|
+
kapso_api_key = ENV['KAPSO_API_KEY']
|
11
|
+
phone_number_id = ENV['PHONE_NUMBER_ID']
|
12
|
+
|
13
|
+
unless kapso_api_key && phone_number_id
|
14
|
+
puts "โ Missing credentials. Run: ruby sdk_test.rb"
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
|
18
|
+
client = WhatsAppCloudApi::Client.new(
|
19
|
+
kapso_api_key: kapso_api_key,
|
20
|
+
base_url: ENV['WHATSAPP_BASE_URL'] || 'https://app.kapso.ai/api/meta',
|
21
|
+
debug: true
|
22
|
+
)
|
23
|
+
|
24
|
+
puts "API Key: ***#{kapso_api_key[-4..-1]} | Phone: #{phone_number_id}"
|
25
|
+
|
26
|
+
print "Destination (+56912345678): "
|
27
|
+
to_number = gets.chomp
|
28
|
+
|
29
|
+
puts "๐ฑ Sending..."
|
30
|
+
|
31
|
+
begin
|
32
|
+
response = client.messages.send_text(
|
33
|
+
phone_number_id: phone_number_id,
|
34
|
+
to: to_number,
|
35
|
+
body: "Test from Ruby SDK - #{Time.now.strftime('%H:%M')}"
|
36
|
+
)
|
37
|
+
|
38
|
+
puts "โ
SUCCESS! Message ID: #{response.messages.first.id}"
|
39
|
+
|
40
|
+
rescue WhatsAppCloudApi::Errors::GraphApiError => e
|
41
|
+
puts "โ ERROR #{e.http_status}: #{e.message}"
|
42
|
+
|
43
|
+
# Check for specific 24-hour window error
|
44
|
+
if e.message.include?("24 hours") || e.message.include?("Re-engagement")
|
45
|
+
puts "โฐ 24-HOUR WINDOW EXPIRED!"
|
46
|
+
puts "๐ก Solutions via Kapso.ai:"
|
47
|
+
puts " โข Check Kapso dashboard for approved templates"
|
48
|
+
puts " โข Run: ruby kapso_template_finder.rb (discover templates)"
|
49
|
+
puts " โข Run: ruby template_test.rb (test template sending)"
|
50
|
+
else
|
51
|
+
case e.http_status
|
52
|
+
when 401
|
53
|
+
puts "๐ก Check Kapso API key in dashboard"
|
54
|
+
when 400
|
55
|
+
puts "๐ก Check phone number ID or destination format"
|
56
|
+
else
|
57
|
+
puts "๐ก Contact Kapso support"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|