wittyflow 0.1.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3252744ffbeb2f9d18598f0c003bcccdd14fefb68576d31860277bd7bf8abfb
4
- data.tar.gz: 7c7aa2a0fd2bc5cd0a42bd9cc82c5ad9af3fee49d74068bf176b6168b0269555
3
+ metadata.gz: bdc8fbce7e5844bca9a9050807303d746084cc12596b8cd755373633b572111b
4
+ data.tar.gz: 3483c288145246fb8597f7ee91d0c4fc2b9a83ce4897becd32ff3faa4acb5e0e
5
5
  SHA512:
6
- metadata.gz: 97d89d9ecbdd332d0031363eb71487cc530772a78de0791eff85721f8df5285b90adaa453e63bc16dc2f0031b2af9b464cd68ed3e8e7ff99379e1e5adeb5f2f0
7
- data.tar.gz: e9b79e5733fec9b85e92aa0fc7509b458268ab85807786858a681762e472bac2b1b5b7bf7ac822074978565cb2ae1aedbd95516b2988b37b6ce1494267a05e42
6
+ metadata.gz: bfcd365cf908f23631e3be46fb32f19b7ccad546f2eb5807f4f6eabb2492ef654bba3b26992efb1315ce8c12cf75b4a26eba9f819d7acc357fdc4ea90c29009e
7
+ data.tar.gz: cc518905f36f4ad53b98b58f08c161bd1ad7b264576c1443d3e18c7899e26432079c6cc3415b2d60f3efbaa0bc9645990abab8a761f9ee1f2402e412719c2fe4
data/CHANGELOG.md ADDED
@@ -0,0 +1,160 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.0] - 2024-01-XX
9
+
10
+ ### 🚀 Major Release - Complete Rewrite
11
+
12
+ This is a major release with breaking changes. The gem has been completely rewritten with modern Ruby patterns and production-ready features.
13
+
14
+ ### Added
15
+
16
+ - **Modern Ruby Support**: Now requires Ruby 3.0+ for better performance and security
17
+ - **Zeitwerk Autoloading**: Automatic code loading for better performance
18
+ - **Comprehensive Error Handling**: Specific error classes for different failure scenarios
19
+ - `Wittyflow::ConfigurationError` - Invalid configuration
20
+ - `Wittyflow::ValidationError` - Invalid parameters
21
+ - `Wittyflow::AuthenticationError` - Invalid credentials
22
+ - `Wittyflow::NetworkError` - Network timeouts and connectivity issues
23
+ - `Wittyflow::APIError` - API-specific errors
24
+ - **Retry Logic**: Automatic retry mechanism for network failures with configurable attempts and delays
25
+ - **Global Configuration**: Configure the gem globally for easier Rails integration
26
+ - **Bulk SMS Support**: Send SMS to multiple recipients with `send_bulk_sms` method
27
+ - **Enhanced Phone Number Formatting**: Intelligent handling of various phone number formats
28
+ - **Comprehensive Test Suite**: 90%+ test coverage with RSpec, WebMock, and VCR
29
+ - **Rails Integration Examples**: Detailed examples for Rails applications including:
30
+ - Service classes
31
+ - Background jobs with Sidekiq
32
+ - Model integration
33
+ - Controller usage
34
+ - Database logging
35
+ - **Production Features**:
36
+ - Request timeouts and retries
37
+ - Proper logging support
38
+ - User-Agent headers
39
+ - HTTP connection pooling via HTTParty
40
+ - **Development Tools**:
41
+ - RuboCop with modern rules
42
+ - SimpleCov for coverage reporting
43
+ - YARD for documentation
44
+ - Guard for automated testing
45
+
46
+ ### Changed
47
+
48
+ - **BREAKING**: Minimum Ruby version is now 3.0.0
49
+ - **BREAKING**: Main API has changed to use keyword arguments:
50
+ ```ruby
51
+ # Old (still works but deprecated)
52
+ client.send_sms(sender, phone, message)
53
+
54
+ # New
55
+ client.send_sms(from: sender, to: phone, message: message)
56
+ ```
57
+ - **BREAKING**: Error handling now uses specific exception classes instead of generic errors
58
+ - Updated HTTParty to latest version (0.21.x)
59
+ - Improved phone number validation and formatting
60
+ - Better response parsing and error messages
61
+
62
+ ### Deprecated
63
+
64
+ - `Wittyflow::Sms` class is now deprecated in favor of `Wittyflow::Client`
65
+ - Old positional argument methods (still work but show deprecation warnings)
66
+
67
+ ### Removed
68
+
69
+ - Ruby 2.x support (breaking change)
70
+ - Legacy error handling patterns
71
+
72
+ ### Fixed
73
+
74
+ - Phone number formatting edge cases
75
+ - Memory leaks in HTTP connections
76
+ - Race conditions in concurrent usage
77
+ - Proper handling of network timeouts
78
+
79
+ ### Security
80
+
81
+ - Updated all dependencies to latest secure versions
82
+ - Added proper input validation and sanitization
83
+ - Removed potential security vulnerabilities in error messages
84
+
85
+ ## [0.1.0] - 2023-XX-XX
86
+
87
+ ### Added
88
+ - Initial release
89
+ - Basic SMS sending functionality
90
+ - Flash SMS support
91
+ - Account balance checking
92
+ - Message status tracking
93
+ - Basic error handling
94
+
95
+ ### Requirements
96
+ - Ruby 2.0+
97
+ - HTTParty 0.17.x
98
+
99
+ ---
100
+
101
+ ## Migration Guide
102
+
103
+ ### From v0.1.x to v1.0.0
104
+
105
+ 1. **Update Ruby Version**: Ensure you're using Ruby 3.0 or later
106
+ 2. **Update Dependencies**: Run `bundle update`
107
+ 3. **Update API Calls**: Change to keyword arguments:
108
+ ```ruby
109
+ # Before
110
+ sms = Wittyflow::Sms.new(app_id, app_secret)
111
+ sms.send_sms("Sender", "0241234567", "Message")
112
+
113
+ # After
114
+ client = Wittyflow::Client.new(app_id: app_id, app_secret: app_secret)
115
+ client.send_sms(from: "Sender", to: "0241234567", message: "Message")
116
+ ```
117
+ 4. **Update Error Handling**: Use specific exception classes:
118
+ ```ruby
119
+ # Before
120
+ begin
121
+ sms.send_sms(...)
122
+ rescue => e
123
+ puts "Error: #{e.message}"
124
+ end
125
+
126
+ # After
127
+ begin
128
+ client.send_sms(...)
129
+ rescue Wittyflow::AuthenticationError => e
130
+ # Handle auth errors
131
+ rescue Wittyflow::NetworkError => e
132
+ # Handle network errors
133
+ rescue Wittyflow::ValidationError => e
134
+ # Handle validation errors
135
+ end
136
+ ```
137
+ 5. **Add Configuration**: Set up global configuration in Rails initializer:
138
+ ```ruby
139
+ # config/initializers/wittyflow.rb
140
+ Wittyflow.configure do |config|
141
+ config.app_id = ENV['WITTYFLOW_APP_ID']
142
+ config.app_secret = ENV['WITTYFLOW_APP_SECRET']
143
+ end
144
+ ```
145
+
146
+ ### Breaking Changes Summary
147
+
148
+ - **Ruby 3.0+ Required**: The gem no longer supports Ruby 2.x
149
+ - **Keyword Arguments**: All methods now use keyword arguments instead of positional arguments
150
+ - **New Error Classes**: Generic errors have been replaced with specific error classes
151
+ - **Configuration Changes**: New configuration system with global and instance-level options
152
+ - **HTTParty Update**: Updated to latest version which may have its own breaking changes
153
+
154
+ ### New Features You Can Use
155
+
156
+ - **Bulk SMS**: Send to multiple recipients at once
157
+ - **Retry Logic**: Automatic retries for failed requests
158
+ - **Better Formatting**: Improved phone number handling
159
+ - **Rails Integration**: Comprehensive examples for Rails apps
160
+ - **Testing Helpers**: Built-in test helpers for easier testing
data/Guardfile ADDED
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A sample Guardfile
4
+ # More info at https://github.com/guard/guard#readme
5
+
6
+ guard :rspec, cmd: "bundle exec rspec" do
7
+ require "guard/rspec/dsl"
8
+ dsl = Guard::RSpec::Dsl.new(self)
9
+
10
+ # Feel free to open issues for suggestions and improvements
11
+
12
+ # RSpec files
13
+ rspec = dsl.rspec
14
+ watch(rspec.spec_helper) { rspec.spec_dir }
15
+ watch(rspec.spec_support) { rspec.spec_dir }
16
+ watch(rspec.spec_files)
17
+
18
+ # Ruby files
19
+ ruby = dsl.ruby
20
+ dsl.watch_spec_files_for(ruby.lib_files)
21
+
22
+ # Wittyflow specific files
23
+ watch(%r{^lib/wittyflow/(.+)\.rb$}) { |m| "spec/wittyflow/#{m[1]}_spec.rb" }
24
+ watch(%r{^lib/wittyflow\.rb$}) { "spec/wittyflow_spec.rb" }
25
+ end
26
+
27
+ guard :rubocop, all_on_start: false, cli: ["--format", "emacs"] do
28
+ watch(/.+\.rb$/)
29
+ watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
30
+ end
data/README.md CHANGED
@@ -1,8 +1,21 @@
1
- # Wittyflow
1
+ # Wittyflow Ruby Gem
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/wittyflow`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ [![Gem Version](https://badge.fury.io/rb/wittyflow.svg)](https://badge.fury.io/rb/wittyflow)
4
+ [![Ruby](https://github.com/charlesagyemang/wittyflow_sms_ruby_gem/actions/workflows/ruby.yml/badge.svg)](https://github.com/charlesagyemang/wittyflow_sms_ruby_gem/actions/workflows/ruby.yml)
4
5
 
5
- TODO: Delete this and the text above, and describe your gem
6
+ A production-ready Ruby gem for integrating with the [Wittyflow SMS API](https://wittyflow.com/). Send SMS messages, check delivery status, and manage your account with a clean, modern Ruby interface.
7
+
8
+ ## Features
9
+
10
+ - 🚀 **Modern Ruby**: Requires Ruby 3.0+ with Zeitwerk autoloading
11
+ - 📱 **Full SMS API**: Send regular SMS, flash SMS, and bulk messaging
12
+ - 🔄 **Retry Logic**: Built-in retry mechanism for network failures
13
+ - 🛡️ **Error Handling**: Comprehensive error types with detailed messages
14
+ - 📊 **Account Management**: Check balance and message delivery status
15
+ - 🌍 **Phone Formatting**: Intelligent phone number formatting for Ghana
16
+ - 🧪 **Well Tested**: 90%+ test coverage with RSpec
17
+ - 📖 **Rails Ready**: Easy integration with Rails applications
18
+ - 🔧 **Configurable**: Global and per-instance configuration options
6
19
 
7
20
  ## Installation
8
21
 
@@ -14,30 +27,469 @@ gem 'wittyflow'
14
27
 
15
28
  And then execute:
16
29
 
17
- $ bundle install
30
+ ```bash
31
+ $ bundle install
32
+ ```
18
33
 
19
34
  Or install it yourself as:
20
35
 
21
- $ gem install wittyflow
36
+ ```bash
37
+ $ gem install wittyflow
38
+ ```
39
+
40
+ ## Configuration
41
+
42
+ ### Global Configuration (Recommended for Rails)
43
+
44
+ ```ruby
45
+ # config/initializers/wittyflow.rb
46
+ Wittyflow.configure do |config|
47
+ config.app_id = ENV['WITTYFLOW_APP_ID']
48
+ config.app_secret = ENV['WITTYFLOW_APP_SECRET']
49
+ config.timeout = 30
50
+ config.retries = 3
51
+ config.retry_delay = 1
52
+ config.default_country_code = "233" # Ghana
53
+ end
54
+ ```
55
+
56
+ ### Environment Variables
57
+
58
+ Create a `.env` file or set environment variables:
59
+
60
+ ```bash
61
+ WITTYFLOW_APP_ID=your_app_id_here
62
+ WITTYFLOW_APP_SECRET=your_app_secret_here
63
+ ```
22
64
 
23
65
  ## Usage
24
66
 
25
- TODO: Write usage instructions here
67
+ ### Basic SMS Sending
68
+
69
+ ```ruby
70
+ # Using global configuration
71
+ client = Wittyflow::Client.new
72
+
73
+ # Send regular SMS
74
+ response = client.send_sms(
75
+ from: "YourApp",
76
+ to: "0241234567",
77
+ message: "Hello from Wittyflow!"
78
+ )
79
+
80
+ # Send flash SMS (appears directly on screen)
81
+ response = client.send_flash_sms(
82
+ from: "YourApp",
83
+ to: "0241234567",
84
+ message: "Urgent: Your verification code is 123456"
85
+ )
86
+ ```
87
+
88
+ ### Instance Configuration
89
+
90
+ ```ruby
91
+ # Per-instance configuration
92
+ client = Wittyflow::Client.new(
93
+ app_id: "your_app_id",
94
+ app_secret: "your_app_secret",
95
+ timeout: 60,
96
+ retries: 5
97
+ )
98
+
99
+ response = client.send_sms(
100
+ from: "YourApp",
101
+ to: "+233241234567",
102
+ message: "Hello World!"
103
+ )
104
+ ```
105
+
106
+ ### Bulk SMS
107
+
108
+ ```ruby
109
+ # Send to multiple recipients
110
+ recipients = ["0241234567", "0241234568", "0241234569"]
111
+
112
+ results = client.send_bulk_sms(
113
+ from: "YourApp",
114
+ to: recipients,
115
+ message: "Bulk message to all recipients"
116
+ )
117
+
118
+ # Results is an array with response for each recipient
119
+ results.each_with_index do |result, index|
120
+ puts "Message to #{recipients[index]}: #{result['status']}"
121
+ end
122
+ ```
123
+
124
+ ### Message Status Tracking
125
+
126
+ ```ruby
127
+ # Check delivery status
128
+ status_response = client.message_status("message_id_from_send_response")
129
+ puts "Message status: #{status_response['data']['status']}"
130
+ ```
131
+
132
+ ### Account Balance
133
+
134
+ ```ruby
135
+ # Check account balance
136
+ balance_response = client.account_balance
137
+ puts "Balance: #{balance_response['data']['balance']} #{balance_response['data']['currency']}"
138
+ ```
139
+
140
+ ## Rails Integration
141
+
142
+ ### 1. SMS Service Class
143
+
144
+ ```ruby
145
+ # app/services/sms_service.rb
146
+ class SmsService
147
+ include ActiveModel::Model
148
+
149
+ attr_accessor :to, :message, :from
150
+
151
+ validates :to, :message, presence: true
152
+ validates :from, presence: true, length: { maximum: 11 }
153
+
154
+ def initialize(attributes = {})
155
+ super
156
+ @from ||= Rails.application.credentials.sms_sender_id || "YourApp"
157
+ end
158
+
159
+ def send_sms
160
+ return false unless valid?
161
+
162
+ begin
163
+ response = wittyflow_client.send_sms(
164
+ from: from,
165
+ to: to,
166
+ message: message
167
+ )
168
+
169
+ # Log the response
170
+ Rails.logger.info "SMS sent successfully: #{response}"
171
+
172
+ # Store in database if needed
173
+ SmsLog.create!(
174
+ recipient: to,
175
+ message: message,
176
+ sender: from,
177
+ external_id: response.dig('data', 'message_id'),
178
+ status: 'sent',
179
+ response: response
180
+ )
181
+
182
+ true
183
+ rescue Wittyflow::Error => e
184
+ Rails.logger.error "SMS sending failed: #{e.message}"
185
+ errors.add(:base, "Failed to send SMS: #{e.message}")
186
+ false
187
+ end
188
+ end
189
+
190
+ private
191
+
192
+ def wittyflow_client
193
+ @wittyflow_client ||= Wittyflow::Client.new
194
+ end
195
+ end
196
+ ```
197
+
198
+ ### 2. Controller Integration
199
+
200
+ ```ruby
201
+ # app/controllers/notifications_controller.rb
202
+ class NotificationsController < ApplicationController
203
+ before_action :authenticate_user!
204
+
205
+ def send_sms
206
+ @sms_service = SmsService.new(sms_params)
207
+
208
+ if @sms_service.send_sms
209
+ flash[:notice] = 'SMS sent successfully!'
210
+ redirect_to notifications_path
211
+ else
212
+ flash[:alert] = @sms_service.errors.full_messages.join(', ')
213
+ render :new
214
+ end
215
+ end
216
+
217
+ private
218
+
219
+ def sms_params
220
+ params.require(:sms_service).permit(:to, :message, :from)
221
+ end
222
+ end
223
+ ```
224
+
225
+ ### 3. Background Jobs with Sidekiq
226
+
227
+ ```ruby
228
+ # app/jobs/send_sms_job.rb
229
+ class SendSmsJob < ApplicationJob
230
+ queue_as :default
231
+
232
+ retry_on Wittyflow::NetworkError, wait: :exponentially_longer, attempts: 3
233
+ retry_on Wittyflow::APIError, wait: 30.seconds, attempts: 2
234
+
235
+ def perform(recipient, message, sender = nil)
236
+ client = Wittyflow::Client.new
237
+
238
+ response = client.send_sms(
239
+ from: sender || Rails.application.credentials.sms_sender_id,
240
+ to: recipient,
241
+ message: message
242
+ )
243
+
244
+ # Update database record if needed
245
+ SmsLog.find_by(recipient: recipient, message: message)
246
+ &.update!(external_id: response.dig('data', 'message_id'))
247
+ end
248
+ end
249
+
250
+ # Usage in controllers or models
251
+ SendSmsJob.perform_later(user.phone, "Welcome to our service!", "YourApp")
252
+ ```
253
+
254
+ ### 4. Model Integration
255
+
256
+ ```ruby
257
+ # app/models/user.rb
258
+ class User < ApplicationRecord
259
+ after_create :send_welcome_sms
260
+
261
+ def send_sms(message, sender = nil)
262
+ return false unless phone.present?
263
+
264
+ SmsService.new(
265
+ to: phone,
266
+ message: message,
267
+ from: sender
268
+ ).send_sms
269
+ end
270
+
271
+ def send_verification_code
272
+ code = generate_verification_code
273
+ update(verification_code: code)
274
+
275
+ send_sms("Your verification code is: #{code}")
276
+ end
277
+
278
+ private
279
+
280
+ def send_welcome_sms
281
+ SendSmsJob.perform_later(
282
+ phone,
283
+ "Welcome to #{Rails.application.class.module_parent_name}! Thanks for joining us.",
284
+ "YourApp"
285
+ )
286
+ end
287
+
288
+ def generate_verification_code
289
+ SecureRandom.random_number(999999).to_s.rjust(6, '0')
290
+ end
291
+ end
292
+ ```
293
+
294
+ ### 5. Database Logging
295
+
296
+ ```ruby
297
+ # db/migrate/xxx_create_sms_logs.rb
298
+ class CreateSmsLogs < ActiveRecord::Migration[7.0]
299
+ def change
300
+ create_table :sms_logs do |t|
301
+ t.string :recipient, null: false
302
+ t.text :message, null: false
303
+ t.string :sender
304
+ t.string :external_id
305
+ t.string :status, default: 'pending'
306
+ t.json :response
307
+ t.timestamps
308
+ end
309
+
310
+ add_index :sms_logs, :recipient
311
+ add_index :sms_logs, :external_id
312
+ add_index :sms_logs, :status
313
+ end
314
+ end
315
+
316
+ # app/models/sms_log.rb
317
+ class SmsLog < ApplicationRecord
318
+ validates :recipient, :message, presence: true
319
+
320
+ enum status: {
321
+ pending: 'pending',
322
+ sent: 'sent',
323
+ delivered: 'delivered',
324
+ failed: 'failed'
325
+ }
326
+
327
+ scope :recent, -> { order(created_at: :desc) }
328
+ scope :for_recipient, ->(phone) { where(recipient: phone) }
329
+ end
330
+ ```
331
+
332
+ ## Phone Number Formats
333
+
334
+ The gem automatically handles various phone number formats for Ghana:
335
+
336
+ ```ruby
337
+ # All of these formats work:
338
+ client.send_sms(from: "App", to: "0241234567", message: "Hello") # Local with 0
339
+ client.send_sms(from: "App", to: "241234567", message: "Hello") # Local without 0
340
+ client.send_sms(from: "App", to: "+233241234567", message: "Hello") # International
341
+ client.send_sms(from: "App", to: "233241234567", message: "Hello") # Country code only
342
+
343
+ # They all get formatted to: "233241234567"
344
+ ```
345
+
346
+ ## Error Handling
347
+
348
+ The gem provides specific error types for different scenarios:
349
+
350
+ ```ruby
351
+ begin
352
+ client.send_sms(from: "App", to: "0241234567", message: "Hello")
353
+ rescue Wittyflow::AuthenticationError => e
354
+ # Invalid app_id or app_secret
355
+ puts "Authentication failed: #{e.message}"
356
+ rescue Wittyflow::ValidationError => e
357
+ # Invalid parameters (missing required fields, etc.)
358
+ puts "Validation error: #{e.message}"
359
+ rescue Wittyflow::NetworkError => e
360
+ # Network timeout or connection issues
361
+ puts "Network error: #{e.message}"
362
+ rescue Wittyflow::APIError => e
363
+ # API-specific errors (rate limiting, server errors)
364
+ puts "API error: #{e.message}"
365
+ rescue Wittyflow::Error => e
366
+ # Any other Wittyflow-related error
367
+ puts "Wittyflow error: #{e.message}"
368
+ end
369
+ ```
370
+
371
+ ## Testing
372
+
373
+ ### With RSpec
374
+
375
+ ```ruby
376
+ # spec/support/wittyflow_helpers.rb
377
+ module WittyflowHelpers
378
+ def stub_wittyflow_success(response_data = {})
379
+ allow_any_instance_of(Wittyflow::Client)
380
+ .to receive(:send_sms)
381
+ .and_return({
382
+ 'status' => 'success',
383
+ 'data' => { 'message_id' => 'msg_123' }.merge(response_data)
384
+ })
385
+ end
386
+
387
+ def stub_wittyflow_error(error_class = Wittyflow::APIError, message = "API Error")
388
+ allow_any_instance_of(Wittyflow::Client)
389
+ .to receive(:send_sms)
390
+ .and_raise(error_class, message)
391
+ end
392
+ end
393
+
394
+ # In your specs
395
+ RSpec.configure do |config|
396
+ config.include WittyflowHelpers
397
+ end
398
+
399
+ # spec/services/sms_service_spec.rb
400
+ RSpec.describe SmsService do
401
+ describe '#send_sms' do
402
+ let(:service) { described_class.new(to: '0241234567', message: 'Test') }
403
+
404
+ context 'when API call succeeds' do
405
+ before { stub_wittyflow_success }
406
+
407
+ it 'returns true' do
408
+ expect(service.send_sms).to be true
409
+ end
410
+ end
411
+
412
+ context 'when API call fails' do
413
+ before { stub_wittyflow_error(Wittyflow::NetworkError, 'Network timeout') }
414
+
415
+ it 'returns false and adds error' do
416
+ expect(service.send_sms).to be false
417
+ expect(service.errors[:base]).to include('Failed to send SMS: Network timeout')
418
+ end
419
+ end
420
+ end
421
+ end
422
+ ```
26
423
 
27
424
  ## Development
28
425
 
29
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
426
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt.
427
+
428
+ ### Available Rake Tasks
429
+
430
+ ```bash
431
+ rake spec # Run all tests
432
+ rake rubocop # Run RuboCop linter
433
+ rake quality # Run all quality checks (tests + linting)
434
+ rake coverage # Generate test coverage report
435
+ rake doc # Generate YARD documentation
436
+ ```
437
+
438
+ ### Contributing
30
439
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
440
+ 1. Fork the repository
441
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
442
+ 3. Write tests for your changes
443
+ 4. Ensure all tests pass (`rake quality`)
444
+ 5. Commit your changes (`git commit -am 'Add some feature'`)
445
+ 6. Push to the branch (`git push origin my-new-feature`)
446
+ 7. Create a Pull Request
32
447
 
33
- ## Contributing
448
+ ## Changelog
34
449
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/wittyflow. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/wittyflow/blob/master/CODE_OF_CONDUCT.md).
450
+ ### v1.0.0 (Latest)
451
+
452
+ - **Breaking Changes**: Requires Ruby 3.0+
453
+ - Complete rewrite with modern Ruby patterns
454
+ - Added comprehensive error handling with specific error types
455
+ - Added retry logic for network failures
456
+ - Added bulk SMS support
457
+ - Added extensive test suite (90%+ coverage)
458
+ - Added Rails integration examples
459
+ - Added global configuration support
460
+ - Improved phone number formatting
461
+ - Added Zeitwerk autoloading
462
+
463
+ ### v0.1.0 (Legacy)
464
+
465
+ - Basic SMS sending functionality
466
+ - Minimal error handling
467
+ - Ruby 2.0+ support
468
+
469
+ ## Migration from v0.x
470
+
471
+ If you're upgrading from v0.x, here are the key changes:
472
+
473
+ ```ruby
474
+ # Old way (still works but deprecated)
475
+ sms = Wittyflow::Sms.new(app_id, app_secret)
476
+ sms.send_sms(sender, phone, message)
477
+
478
+ # New way
479
+ client = Wittyflow::Client.new(app_id: app_id, app_secret: app_secret)
480
+ client.send_sms(from: sender, to: phone, message: message)
481
+ ```
36
482
 
37
483
  ## License
38
484
 
39
485
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
40
486
 
487
+ ## Support
488
+
489
+ - 📧 Email: micnkru@gmail.com
490
+ - 🐛 [Report Issues](https://github.com/charlesagyemang/wittyflow_sms_ruby_gem/issues)
491
+ - 📖 [Documentation](https://github.com/charlesagyemang/wittyflow_sms_ruby_gem)
492
+
41
493
  ## Code of Conduct
42
494
 
43
- Everyone interacting in the Wittyflow project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/wittyflow/blob/master/CODE_OF_CONDUCT.md).
495
+ Everyone interacting in the Wittyflow project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/charlesagyemang/wittyflow_sms_ruby_gem/blob/main/CODE_OF_CONDUCT.md).