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,241 @@
1
+ # frozen_string_literal: true
2
+
3
+ # WhatsApp Advanced Messaging Features Examples
4
+ # Demonstrates voice notes, group messaging, location requests
5
+
6
+ require 'kapso-client-ruby'
7
+ require 'dotenv'
8
+
9
+ Dotenv.load
10
+
11
+ # Initialize client
12
+ client = KapsoClientRuby::Client.new(
13
+ access_token: ENV['WHATSAPP_ACCESS_TOKEN']
14
+ )
15
+
16
+ phone_number_id = ENV['PHONE_NUMBER_ID']
17
+ recipient = '+1234567890'
18
+ group_id = ENV['GROUP_ID'] || '120363XXXXXXXXX@g.us' # WhatsApp group ID format
19
+
20
+ puts "=== Advanced Messaging Features (Week 4) ===\n\n"
21
+
22
+ # 1. VOICE NOTES
23
+
24
+ puts "1. Sending voice note..."
25
+
26
+ begin
27
+ response = client.messages.send_audio(
28
+ phone_number_id: phone_number_id,
29
+ to: recipient,
30
+ audio: {
31
+ link: 'https://example.com/voice-message.ogg' # OGG/OPUS format for voice notes
32
+ },
33
+ voice: true # Set to true for voice notes
34
+ )
35
+
36
+ puts "✓ Voice note sent! ID: #{response.messages.first.id}\n\n"
37
+ rescue StandardError => e
38
+ puts "✗ Error: #{e.message}\n\n"
39
+ end
40
+
41
+ # Regular audio (not a voice note)
42
+ puts "1b. Sending regular audio..."
43
+
44
+ begin
45
+ response = client.messages.send_audio(
46
+ phone_number_id: phone_number_id,
47
+ to: recipient,
48
+ audio: { link: 'https://example.com/music.mp3' },
49
+ voice: false # Or omit - defaults to false
50
+ )
51
+
52
+ puts "✓ Audio sent! ID: #{response.messages.first.id}\n\n"
53
+ rescue StandardError => e
54
+ puts "✗ Error: #{e.message}\n\n"
55
+ end
56
+
57
+ # 2. GROUP MESSAGING
58
+
59
+ puts "2. Sending text message to group..."
60
+
61
+ begin
62
+ response = client.messages.send_text(
63
+ phone_number_id: phone_number_id,
64
+ to: group_id,
65
+ body: 'Hello everyone! This is a group message.',
66
+ recipient_type: 'group' # Set to 'group' for group messages
67
+ )
68
+
69
+ puts "✓ Group message sent! ID: #{response.messages.first.id}\n\n"
70
+ rescue StandardError => e
71
+ puts "✗ Error: #{e.message}\n\n"
72
+ end
73
+
74
+ # Sending image to group
75
+ puts "2b. Sending image to group..."
76
+
77
+ begin
78
+ response = client.messages.send_image(
79
+ phone_number_id: phone_number_id,
80
+ to: group_id,
81
+ image: {
82
+ link: 'https://example.com/team-photo.jpg'
83
+ },
84
+ caption: 'Team photo from our last event!',
85
+ recipient_type: 'group'
86
+ )
87
+
88
+ puts "✓ Group image sent! ID: #{response.messages.first.id}\n\n"
89
+ rescue StandardError => e
90
+ puts "✗ Error: #{e.message}\n\n"
91
+ end
92
+
93
+ # Sending video to group
94
+ puts "2c. Sending video to group..."
95
+
96
+ begin
97
+ response = client.messages.send_video(
98
+ phone_number_id: phone_number_id,
99
+ to: group_id,
100
+ video: {
101
+ link: 'https://example.com/presentation.mp4'
102
+ },
103
+ caption: 'Check out our new product demo!',
104
+ recipient_type: 'group'
105
+ )
106
+
107
+ puts "✓ Group video sent! ID: #{response.messages.first.id}\n\n"
108
+ rescue StandardError => e
109
+ puts "✗ Error: #{e.message}\n\n"
110
+ end
111
+
112
+ # 3. LOCATION REQUEST
113
+
114
+ puts "3. Requesting user location..."
115
+
116
+ begin
117
+ response = client.messages.send_interactive_location_request(
118
+ phone_number_id: phone_number_id,
119
+ to: recipient,
120
+ body_text: 'Please share your location so we can provide better service.',
121
+ footer_text: 'Your location will only be used for this delivery'
122
+ )
123
+
124
+ puts "✓ Location request sent! ID: #{response.messages.first.id}\n\n"
125
+ rescue StandardError => e
126
+ puts "✗ Error: #{e.message}\n\n"
127
+ end
128
+
129
+ # Location request with header
130
+ puts "3b. Location request with image header..."
131
+
132
+ begin
133
+ response = client.messages.send_interactive_location_request(
134
+ phone_number_id: phone_number_id,
135
+ to: recipient,
136
+ header: {
137
+ type: 'image',
138
+ image: { link: 'https://example.com/map-icon.png' }
139
+ },
140
+ body_text: 'Help us serve you better by sharing your current location.',
141
+ footer_text: 'Tap to share location'
142
+ )
143
+
144
+ puts "✓ Location request with header sent! ID: #{response.messages.first.id}\n\n"
145
+ rescue StandardError => e
146
+ puts "✗ Error: #{e.message}\n\n"
147
+ end
148
+
149
+ # 4. VALIDATION TESTS
150
+
151
+ puts "4. Testing validations...\n"
152
+
153
+ # Test invalid recipient_type
154
+ puts " Testing recipient_type validation..."
155
+ begin
156
+ client.messages.send_text(
157
+ phone_number_id: phone_number_id,
158
+ to: recipient,
159
+ body: 'Test',
160
+ recipient_type: 'broadcast' # Invalid type
161
+ )
162
+ puts " ✗ Validation failed\n"
163
+ rescue ArgumentError => e
164
+ puts " ✓ Validation passed: #{e.message}\n"
165
+ end
166
+
167
+ puts "\n=== All advanced features demonstrated! ===\n"
168
+
169
+ # USE CASES
170
+
171
+ puts "\n=== Real-World Use Cases ===\n"
172
+
173
+ # Customer Support: Voice response
174
+ def send_voice_support_message(client, phone_number_id, customer_phone)
175
+ client.messages.send_audio(
176
+ phone_number_id: phone_number_id,
177
+ to: customer_phone,
178
+ audio: { link: 'https://support.example.com/responses/how-to-reset-password.ogg' },
179
+ voice: true
180
+ )
181
+ end
182
+
183
+ # Team Announcements: Group messaging
184
+ def send_team_announcement(client, phone_number_id, team_group_id)
185
+ client.messages.send_text(
186
+ phone_number_id: phone_number_id,
187
+ to: team_group_id,
188
+ body: '📢 Team Meeting Alert: All-hands meeting tomorrow at 10 AM in Conference Room A.',
189
+ recipient_type: 'group'
190
+ )
191
+ end
192
+
193
+ # Delivery Service: Location request
194
+ def request_delivery_location(client, phone_number_id, customer_phone)
195
+ client.messages.send_interactive_location_request(
196
+ phone_number_id: phone_number_id,
197
+ to: customer_phone,
198
+ header: {
199
+ type: 'text',
200
+ text: 'Delivery Service'
201
+ },
202
+ body_text: '🚚 Your order is ready for delivery! Please share your current location for accurate delivery.',
203
+ footer_text: 'We respect your privacy'
204
+ )
205
+ end
206
+
207
+ # Educational: Group study materials
208
+ def share_study_materials_with_group(client, phone_number_id, study_group_id)
209
+ client.messages.send_video(
210
+ phone_number_id: phone_number_id,
211
+ to: study_group_id,
212
+ video: { link: 'https://edu.example.com/lectures/physics-101.mp4' },
213
+ caption: '📚 Physics 101 - Lecture 5: Thermodynamics. Watch before next class!',
214
+ recipient_type: 'group'
215
+ )
216
+ end
217
+
218
+ # Real Estate: Property location sharing
219
+ def request_property_viewing_location(client, phone_number_id, potential_buyer)
220
+ client.messages.send_interactive_location_request(
221
+ phone_number_id: phone_number_id,
222
+ to: potential_buyer,
223
+ header: {
224
+ type: 'image',
225
+ image: { link: 'https://realestate.example.com/properties/oceanview-villa.jpg' }
226
+ },
227
+ body_text: 'Interested in viewing this property? Share your location and we\'ll calculate the best route for you.',
228
+ footer_text: 'Premium Real Estate Services'
229
+ )
230
+ end
231
+
232
+ # Community Management: Group updates with media
233
+ def send_community_update(client, phone_number_id, community_group_id)
234
+ client.messages.send_image(
235
+ phone_number_id: phone_number_id,
236
+ to: community_group_id,
237
+ image: { link: 'https://community.example.com/events/summer-festival-poster.jpg' },
238
+ caption: '🎉 Summer Festival this weekend! Join us for food, music, and fun. See you there!',
239
+ recipient_type: 'group'
240
+ )
241
+ end
@@ -1,137 +1,140 @@
1
- # frozen_string_literal: true
2
-
3
- require 'kapso_client_ruby'
4
-
5
- # Example 1: Basic Text Message
6
- puts "=== Basic Text Message ==="
7
-
8
- begin
9
- # Initialize client with access token (direct Meta API)
10
- client = KapsoClientRuby::Client.new(
11
- access_token: ENV['WHATSAPP_ACCESS_TOKEN']
12
- )
13
-
14
- # Send a simple text message
15
- response = client.messages.send_text(
16
- phone_number_id: ENV['PHONE_NUMBER_ID'],
17
- to: '+56912345678',
18
- body: 'Hello! This is a test message from Ruby SDK.'
19
- )
20
-
21
- puts "Message sent successfully!"
22
- puts "Message ID: #{response.messages.first.id}"
23
- puts "Contact: #{response.contacts.first.wa_id}"
24
-
25
- rescue KapsoClientRuby::Errors::GraphApiError => e
26
- puts "API Error: #{e.message}"
27
- puts "Category: #{e.category}"
28
- puts "HTTP Status: #{e.http_status}"
29
- puts "Retry Action: #{e.retry_hint[:action]}"
30
-
31
- if e.rate_limit?
32
- puts "Rate limited! Retry after: #{e.retry_hint[:retry_after_ms]}ms"
33
- end
34
- end
35
-
36
- # Example 2: Media Message with Error Handling
37
- puts "\n=== Media Message with Error Handling ==="
38
-
39
- begin
40
- # Send image message
41
- response = client.messages.send_image(
42
- phone_number_id: ENV['PHONE_NUMBER_ID'],
43
- to: '+1234567890',
44
- image: {
45
- link: 'https://example.com/image.jpg',
46
- caption: 'Check out this image!'
47
- }
48
- )
49
-
50
- puts "Image message sent: #{response.messages.first.id}"
51
-
52
- rescue KapsoClientRuby::Errors::GraphApiError => e
53
- case e.category
54
- when :media
55
- puts "Media error: #{e.details}"
56
- puts "Check your media file URL or format"
57
- when :parameter
58
- puts "Parameter error: #{e.message}"
59
- puts "Check your phone number and recipient format"
60
- when :throttling
61
- puts "Rate limited - waiting before retry"
62
- sleep(e.retry_hint[:retry_after_ms] / 1000.0) if e.retry_hint[:retry_after_ms]
63
- else
64
- puts "Other error: #{e.message}"
65
- end
66
- end
67
-
68
- # Example 3: Template Message
69
- puts "\n=== Template Message ==="
70
-
71
- begin
72
- response = client.messages.send_template(
73
- phone_number_id: ENV['PHONE_NUMBER_ID'],
74
- to: '+1234567890',
75
- name: 'welcome_template',
76
- language: 'en_US',
77
- components: [
78
- {
79
- type: 'body',
80
- parameters: [
81
- { type: 'text', text: 'John Doe' }
82
- ]
83
- }
84
- ]
85
- )
86
-
87
- puts "Template message sent: #{response.messages.first.id}"
88
-
89
- rescue KapsoClientRuby::Errors::GraphApiError => e
90
- if e.template_error?
91
- puts "Template error: #{e.details}"
92
- puts "Check template name, language, and parameters"
93
- else
94
- puts "Error: #{e.message}"
95
- end
96
- end
97
-
98
- # Example 4: Interactive Buttons
99
- puts "\n=== Interactive Buttons ==="
100
-
101
- begin
102
- response = client.messages.send_interactive_buttons(
103
- phone_number_id: ENV['PHONE_NUMBER_ID'],
104
- to: '+1234567890',
105
- body_text: 'Please choose an option:',
106
- buttons: [
107
- {
108
- type: 'reply',
109
- reply: {
110
- id: 'option_1',
111
- title: 'Option 1'
112
- }
113
- },
114
- {
115
- type: 'reply',
116
- reply: {
117
- id: 'option_2',
118
- title: 'Option 2'
119
- }
120
- }
121
- ],
122
- header: {
123
- type: 'text',
124
- text: 'Choose Your Option'
125
- },
126
- footer: {
127
- text: 'Powered by Ruby SDK'
128
- }
129
- )
130
-
131
- puts "Interactive message sent: #{response.messages.first.id}"
132
-
133
- rescue KapsoClientRuby::Errors::GraphApiError => e
134
- puts "Interactive message error: #{e.message}"
135
- end
136
-
1
+ # frozen_string_literal: true
2
+
3
+ require 'kapso-client-ruby'
4
+ require 'dotenv'
5
+
6
+ Dotenv.load
7
+
8
+ # Example 1: Basic Text Message
9
+ puts "=== Basic Text Message ==="
10
+
11
+ begin
12
+ # Initialize client with access token (direct Meta API)
13
+ client = KapsoClientRuby::Client.new(
14
+ access_token: ENV['WHATSAPP_ACCESS_TOKEN']
15
+ )
16
+
17
+ # Send a simple text message
18
+ response = client.messages.send_text(
19
+ phone_number_id: ENV['PHONE_NUMBER_ID'],
20
+ to: '+56912345678',
21
+ body: 'Hello! This is a test message from Ruby SDK.'
22
+ )
23
+
24
+ puts "Message sent successfully!"
25
+ puts "Message ID: #{response.messages.first.id}"
26
+ puts "Contact: #{response.contacts.first.wa_id}"
27
+
28
+ rescue KapsoClientRuby::Errors::GraphApiError => e
29
+ puts "API Error: #{e.message}"
30
+ puts "Category: #{e.category}"
31
+ puts "HTTP Status: #{e.http_status}"
32
+ puts "Retry Action: #{e.retry_hint[:action]}"
33
+
34
+ if e.rate_limit?
35
+ puts "Rate limited! Retry after: #{e.retry_hint[:retry_after_ms]}ms"
36
+ end
37
+ end
38
+
39
+ # Example 2: Media Message with Error Handling
40
+ puts "\n=== Media Message with Error Handling ==="
41
+
42
+ begin
43
+ # Send image message
44
+ response = client.messages.send_image(
45
+ phone_number_id: ENV['PHONE_NUMBER_ID'],
46
+ to: '+1234567890',
47
+ image: {
48
+ link: 'https://example.com/image.jpg',
49
+ caption: 'Check out this image!'
50
+ }
51
+ )
52
+
53
+ puts "Image message sent: #{response.messages.first.id}"
54
+
55
+ rescue KapsoClientRuby::Errors::GraphApiError => e
56
+ case e.category
57
+ when :media
58
+ puts "Media error: #{e.details}"
59
+ puts "Check your media file URL or format"
60
+ when :parameter
61
+ puts "Parameter error: #{e.message}"
62
+ puts "Check your phone number and recipient format"
63
+ when :throttling
64
+ puts "Rate limited - waiting before retry"
65
+ sleep(e.retry_hint[:retry_after_ms] / 1000.0) if e.retry_hint[:retry_after_ms]
66
+ else
67
+ puts "Other error: #{e.message}"
68
+ end
69
+ end
70
+
71
+ # Example 3: Template Message
72
+ puts "\n=== Template Message ==="
73
+
74
+ begin
75
+ response = client.messages.send_template(
76
+ phone_number_id: ENV['PHONE_NUMBER_ID'],
77
+ to: '+1234567890',
78
+ name: 'welcome_template',
79
+ language: 'en_US',
80
+ components: [
81
+ {
82
+ type: 'body',
83
+ parameters: [
84
+ { type: 'text', text: 'John Doe' }
85
+ ]
86
+ }
87
+ ]
88
+ )
89
+
90
+ puts "Template message sent: #{response.messages.first.id}"
91
+
92
+ rescue KapsoClientRuby::Errors::GraphApiError => e
93
+ if e.template_error?
94
+ puts "Template error: #{e.details}"
95
+ puts "Check template name, language, and parameters"
96
+ else
97
+ puts "Error: #{e.message}"
98
+ end
99
+ end
100
+
101
+ # Example 4: Interactive Buttons
102
+ puts "\n=== Interactive Buttons ==="
103
+
104
+ begin
105
+ response = client.messages.send_interactive_buttons(
106
+ phone_number_id: ENV['PHONE_NUMBER_ID'],
107
+ to: '+1234567890',
108
+ body_text: 'Please choose an option:',
109
+ buttons: [
110
+ {
111
+ type: 'reply',
112
+ reply: {
113
+ id: 'option_1',
114
+ title: 'Option 1'
115
+ }
116
+ },
117
+ {
118
+ type: 'reply',
119
+ reply: {
120
+ id: 'option_2',
121
+ title: 'Option 2'
122
+ }
123
+ }
124
+ ],
125
+ header: {
126
+ type: 'text',
127
+ text: 'Choose Your Option'
128
+ },
129
+ footer: {
130
+ text: 'Powered by Ruby SDK'
131
+ }
132
+ )
133
+
134
+ puts "Interactive message sent: #{response.messages.first.id}"
135
+
136
+ rescue KapsoClientRuby::Errors::GraphApiError => e
137
+ puts "Interactive message error: #{e.message}"
138
+ end
139
+
137
140
  puts "\n=== Example completed ==="