mitake_sms 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f0145815894a3f478ba54c0cc151d8753f0dd99bab584128fdeaad3a5e37bf7b
4
+ data.tar.gz: 8a83a7ed6f9b43cced0aa4a1130f361669f0043d78767603f505d7465b3aa773
5
+ SHA512:
6
+ metadata.gz: ec120586bd986581175e851ed2a974cc9452ba1e8f964fa59dad0b23a9564671f62d205339d5f82e90d0fcd21f696c115ef4159c60a88d78a6be6255421e36d4
7
+ data.tar.gz: 1716857937144e700d23a88445468856cbd67c7bd5e921e2ac32987216f24acaab4ebba161dadd58fbcce9641c11fbcfe6be307a940e315b3f0b803237818363
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --require spec_helper
2
+ --format documentation
3
+ --color
4
+ --order random
data/CHANGELOG.md ADDED
@@ -0,0 +1,27 @@
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
+ ## [Unreleased]
9
+
10
+ ## [1.0.0] - 2025-05-24
11
+ ### Added
12
+ - Initial stable release
13
+ - Added SMS sending functionality
14
+ - Support for both single and batch SMS sending
15
+ - Basic error handling and configuration system
16
+ - SimpleCov and SimpleCov-Cobertura for code coverage reporting
17
+ - GitHub Actions workflow for automated testing and code coverage
18
+ - Codecov integration with coverage badge in README
19
+
20
+ ### Changed
21
+ - Refactored configuration system using `Dry::Configurable`
22
+ - Updated error handling with error classes under `MitakeSms::Client` namespace
23
+ - Updated `.gitignore` to exclude `.rspec_status`
24
+
25
+ ### Fixed
26
+ - Fixed `method_missing` issue in configuration system
27
+ - Fixed error class references in tests
data/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # MitakeSms
2
+
3
+ [![codecov](https://codecov.io/gh/7a6163/mitake_sms/graph/badge.svg?token=QNRP1N3TOP)](https://codecov.io/gh/7a6163/mitake_sms)
4
+
5
+ A Ruby client for the Mitake SMS API, providing a simple and efficient way to send SMS messages through the Mitake SMS service.
6
+
7
+ ## Features
8
+
9
+ - Send single SMS messages
10
+ - Send batch SMS messages
11
+ - Configurable API settings
12
+ - Simple and intuitive API
13
+ - Comprehensive error handling
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ ```ruby
20
+ gem 'mitake_sms', github: '7a6163/mitake_sms'
21
+ ```
22
+
23
+ And then execute:
24
+
25
+ ```bash
26
+ $ bundle install
27
+ ```
28
+
29
+ Or install it yourself as:
30
+
31
+ ```bash
32
+ $ gem install mitake_sms
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ ### Configuration
38
+
39
+ Before using the gem, you need to configure it with your Mitake SMS API credentials:
40
+
41
+ ```ruby
42
+ require 'mitake_sms'
43
+
44
+ MitakeSms.configure do |config|
45
+ config.username = 'your_username' # Your Mitake SMS API username
46
+ config.password = 'your_password' # Your Mitake SMS API password
47
+ config.api_url = 'https://smsapi.mitake.com.tw/api/mtk/' # Default API URL
48
+ end
49
+ ```
50
+
51
+ ### Sending a Single SMS
52
+
53
+ ```ruby
54
+ # Send a simple SMS
55
+ response = MitakeSms.send_sms('0912345678', 'Hello, this is a test message!')
56
+
57
+ if response.success?
58
+ puts "Message sent successfully! Message ID: #{response.message_id}"
59
+ puts "Remaining points: #{response.account_point}"
60
+ else
61
+ puts "Failed to send message: #{response.error}"
62
+ end
63
+
64
+ # With additional options
65
+ response = MitakeSms.send_sms(
66
+ '0912345678',
67
+ 'Hello with options!',
68
+ from: 'YourBrand',
69
+ response_url: 'https://your-callback-url.com/delivery-reports',
70
+ client_id: 'your-client-reference-id'
71
+ )
72
+ ```
73
+
74
+ ### Sending Multiple SMS in Batch
75
+
76
+ ```ruby
77
+ messages = [
78
+ { to: '0912345678', text: 'First message' },
79
+ { to: '0922333444', text: 'Second message', from: 'YourBrand' },
80
+ { to: '0933555777', text: 'Third message', response_url: 'https://your-callback-url.com/reports' }
81
+ ]
82
+
83
+ response = MitakeSms.batch_send(messages)
84
+
85
+ if response.success?
86
+ puts "Batch sent successfully!"
87
+ puts "Message ID: #{response.message_id}"
88
+ puts "Remaining points: #{response.account_point}"
89
+ else
90
+ puts "Failed to send batch: #{response.error}"
91
+ end
92
+ ```
93
+
94
+ ### Error Handling
95
+
96
+ The gem provides specific error classes for different types of errors:
97
+
98
+ ```ruby
99
+ begin
100
+ response = MitakeSms.send_sms('invalid', 'test')
101
+ rescue MitakeSms::Client::AuthenticationError => e
102
+ puts "Authentication failed: #{e.message}"
103
+ rescue MitakeSms::Client::InvalidRequestError => e
104
+ puts "Invalid request: #{e.message}"
105
+ rescue MitakeSms::Client::ServerError => e
106
+ puts "Server error: #{e.message}"
107
+ rescue MitakeSms::Client::Error => e
108
+ puts "An error occurred: #{e.message}"
109
+ end
110
+ ```
111
+
112
+ ## Development
113
+
114
+ 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 that will allow you to experiment.
115
+
116
+ To install this gem onto your local machine, run `bundle exec rake install`.
117
+
118
+ ## Contributing
119
+
120
+ Bug reports and pull requests are welcome on GitHub at https://github.com/7a6163/mitake_sms.
121
+
122
+ ## License
123
+
124
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ task default: %i[]
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+ require 'faraday/multipart'
5
+ require_relative 'configuration'
6
+ require_relative 'response'
7
+
8
+ module MitakeSms
9
+ class Client
10
+ class Error < StandardError; end
11
+ class AuthenticationError < Error; end
12
+ class InvalidRequestError < Error; end
13
+ class ServerError < Error; end
14
+
15
+ # Initialize a new MitakeSms::Client
16
+ # @param config [MitakeSms::Configuration] configuration object
17
+ def initialize(config = nil)
18
+ @config = config || MitakeSms.config
19
+ @connection = build_connection
20
+ end
21
+
22
+ # Send a single SMS
23
+ # @param to [String] recipient phone number
24
+ # @param text [String] message content
25
+ # @param options [Hash] additional options
26
+ # @option options [String] :from sender ID
27
+ # @option options [String] :response_url callback URL for delivery reports
28
+ # @option options [String] :client_id client reference ID
29
+ # @return [MitakeSms::Response] response object
30
+ def send_sms(to, text, options = {})
31
+ params = {
32
+ username: @config.username,
33
+ password: @config.password,
34
+ dstaddr: to,
35
+ smbody: text.encode('BIG5', invalid: :replace, undef: :replace, replace: '?')
36
+ }.merge(options.slice(:from, :response_url, :client_id))
37
+
38
+ response = @connection.post('SmSend', params)
39
+ handle_response(response)
40
+ end
41
+
42
+ # Send multiple SMS in a single request
43
+ # @param messages [Array<Hash>] array of message hashes
44
+ # Each hash should contain :to and :text keys, and can include :from, :response_url, :client_id
45
+ # @return [MitakeSms::Response] response object
46
+ def batch_send(messages)
47
+ params = {
48
+ username: @config.username,
49
+ password: @config.password,
50
+ smbody: messages.map do |msg|
51
+ to = msg[:to]
52
+ text = msg[:text].to_s.encode('BIG5', invalid: :replace, undef: :replace, replace: '?')
53
+ "#{to}:#{text}"
54
+ end.join("\n")
55
+ }
56
+ response = @connection.post('SmBulkSend', params)
57
+ handle_response(response)
58
+ end
59
+
60
+ private
61
+
62
+ def build_connection
63
+ Faraday.new(url: @config.api_url) do |conn|
64
+ conn.request :url_encoded
65
+ conn.request :multipart
66
+ conn.adapter Faraday.default_adapter
67
+ conn.options.timeout = @config.timeout
68
+ conn.options.open_timeout = @config.open_timeout
69
+ end
70
+ end
71
+
72
+ def handle_response(response)
73
+ case response.status
74
+ when 200
75
+ Response.new(response.body)
76
+ when 401
77
+ raise AuthenticationError, 'Invalid username or password'
78
+ when 400
79
+ raise InvalidRequestError, 'Invalid request parameters'
80
+ when 500..599
81
+ raise ServerError, "Server error: #{response.status}"
82
+ else
83
+ raise Error, "Unexpected error: #{response.status}"
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry/configurable'
4
+
5
+ module MitakeSms
6
+ class Configuration
7
+ extend Dry::Configurable
8
+
9
+ setting :username, default: ENV['MITAKE_USERNAME']
10
+ setting :password, default: ENV['MITAKE_PASSWORD']
11
+ setting :api_url, default: 'https://smsapi.mitake.com.tw/api/mtk/'
12
+ setting :timeout, default: 30
13
+ setting :open_timeout, default: 5
14
+
15
+ # Provide direct access to configuration values at the class level
16
+ class << self
17
+ def username
18
+ config.username
19
+ end
20
+
21
+ def username=(value)
22
+ config.username = value
23
+ end
24
+
25
+ def password
26
+ config.password
27
+ end
28
+
29
+ def password=(value)
30
+ config.password = value
31
+ end
32
+
33
+ def api_url
34
+ config.api_url
35
+ end
36
+
37
+ def api_url=(value)
38
+ config.api_url = value
39
+ end
40
+
41
+ def timeout
42
+ config.timeout
43
+ end
44
+
45
+ def timeout=(value)
46
+ config.timeout = value
47
+ end
48
+
49
+ def open_timeout
50
+ config.open_timeout
51
+ end
52
+
53
+ def open_timeout=(value)
54
+ config.open_timeout = value
55
+ end
56
+ end
57
+ end
58
+
59
+ # Methods for the MitakeSms module itself
60
+ class << self
61
+ def configure
62
+ yield(config) if block_given?
63
+ end
64
+
65
+ # Return the Dry::Configurable object directly
66
+ def config
67
+ Configuration.config
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MitakeSms
4
+ class Response
5
+ attr_reader :raw_response, :code, :message_id, :account_point, :error
6
+
7
+ def initialize(raw_response)
8
+ @raw_response = raw_response
9
+ parse_response(raw_response)
10
+ end
11
+
12
+ def success?
13
+ @code == '1'
14
+ end
15
+
16
+ def error?
17
+ !success?
18
+ end
19
+
20
+ private
21
+
22
+ def parse_response(response)
23
+ return unless response.is_a?(String)
24
+
25
+ # Split by newline and create a hash from key=value pairs
26
+ @parsed_response = {}
27
+ response.each_line do |line|
28
+ key, value = line.strip.split('=', 2)
29
+ @parsed_response[key] = value if key && value
30
+ end
31
+
32
+ @code = @parsed_response['statuscode']
33
+ @message_id = @parsed_response['msgid']
34
+ @account_point = @parsed_response['AccountPoint']
35
+ @error = @parsed_response['Error']
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MitakeSms
4
+ VERSION = "1.0.0"
5
+ end
data/lib/mitake_sms.rb ADDED
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'mitake_sms/version'
4
+ require_relative 'mitake_sms/configuration'
5
+ require_relative 'mitake_sms/response'
6
+ require_relative 'mitake_sms/client'
7
+
8
+ module MitakeSms
9
+ class Error < StandardError; end
10
+ class AuthenticationError < Error; end
11
+ class InvalidRequestError < Error; end
12
+ class ServerError < Error; end
13
+
14
+ class << self
15
+ # Configure the gem
16
+ # @yield [MitakeSms::Configuration] the configuration object
17
+ # @example
18
+ # MitakeSms.configure do |config|
19
+ # config.username = 'your_username'
20
+ # config.password = 'your_password'
21
+ # end
22
+ def configure
23
+ yield(config) if block_given?
24
+ end
25
+
26
+ # Get the current configuration
27
+ # @return [Dry::Configurable::Config] the configuration object
28
+ def config
29
+ Configuration.config
30
+ end
31
+
32
+ # Create a new client with the current configuration
33
+ # @return [MitakeSms::Client] a new client instance
34
+ def client
35
+ @client ||= Client.new
36
+ end
37
+
38
+ # Send a single SMS message
39
+ # @param to [String] recipient phone number
40
+ # @param text [String] message content
41
+ # @param options [Hash] additional options
42
+ # @option options [String] :from sender ID
43
+ # @option options [String] :response_url callback URL for delivery reports
44
+ # @option options [String] :client_id client reference ID
45
+ # @return [MitakeSms::Response] response object
46
+ def send_sms(to, text, options = {})
47
+ client.send_sms(to, text, options)
48
+ end
49
+
50
+ # Send multiple SMS messages in a single request
51
+ # @param messages [Array<Hash>] array of message hashes
52
+ # Each hash should contain :to and :text keys, and can include :from, :response_url, :client_id
53
+ # @return [MitakeSms::Response] response object
54
+ def batch_send(messages)
55
+ client.batch_send(messages)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,4 @@
1
+ module MitakeSms
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,197 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mitake_sms
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Zac
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: faraday
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '1.0'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '1.0'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '3.0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: faraday-multipart
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0.1'
39
+ - - "<"
40
+ - !ruby/object:Gem::Version
41
+ version: '2.0'
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0.1'
49
+ - - "<"
50
+ - !ruby/object:Gem::Version
51
+ version: '2.0'
52
+ - !ruby/object:Gem::Dependency
53
+ name: dry-configurable
54
+ requirement: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 0.13.0
59
+ - - "<"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 0.13.0
69
+ - - "<"
70
+ - !ruby/object:Gem::Version
71
+ version: '2.0'
72
+ - !ruby/object:Gem::Dependency
73
+ name: rspec
74
+ requirement: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - "~>"
77
+ - !ruby/object:Gem::Version
78
+ version: '3.0'
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: '3.0'
86
+ - !ruby/object:Gem::Dependency
87
+ name: webmock
88
+ requirement: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - "~>"
91
+ - !ruby/object:Gem::Version
92
+ version: '3.14'
93
+ type: :development
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '3.14'
100
+ - !ruby/object:Gem::Dependency
101
+ name: pry
102
+ requirement: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - "~>"
105
+ - !ruby/object:Gem::Version
106
+ version: 0.14.0
107
+ type: :development
108
+ prerelease: false
109
+ version_requirements: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - "~>"
112
+ - !ruby/object:Gem::Version
113
+ version: 0.14.0
114
+ - !ruby/object:Gem::Dependency
115
+ name: rake
116
+ requirement: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - "~>"
119
+ - !ruby/object:Gem::Version
120
+ version: '13.0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - "~>"
126
+ - !ruby/object:Gem::Version
127
+ version: '13.0'
128
+ - !ruby/object:Gem::Dependency
129
+ name: simplecov
130
+ requirement: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - "~>"
133
+ - !ruby/object:Gem::Version
134
+ version: 0.21.0
135
+ type: :development
136
+ prerelease: false
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - "~>"
140
+ - !ruby/object:Gem::Version
141
+ version: 0.21.0
142
+ - !ruby/object:Gem::Dependency
143
+ name: simplecov-cobertura
144
+ requirement: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - "~>"
147
+ - !ruby/object:Gem::Version
148
+ version: '2.1'
149
+ type: :development
150
+ prerelease: false
151
+ version_requirements: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - "~>"
154
+ - !ruby/object:Gem::Version
155
+ version: '2.1'
156
+ description: A simple and efficient Ruby client for sending SMS messages through Mitake
157
+ SMS API
158
+ email:
159
+ - 579103+7a6163@users.noreply.github.com
160
+ executables: []
161
+ extensions: []
162
+ extra_rdoc_files: []
163
+ files:
164
+ - ".rspec"
165
+ - CHANGELOG.md
166
+ - README.md
167
+ - Rakefile
168
+ - lib/mitake_sms.rb
169
+ - lib/mitake_sms/client.rb
170
+ - lib/mitake_sms/configuration.rb
171
+ - lib/mitake_sms/response.rb
172
+ - lib/mitake_sms/version.rb
173
+ - sig/mitake_sms.rbs
174
+ homepage: https://github.com/7a6163/mitake_sms
175
+ licenses: []
176
+ metadata:
177
+ homepage_uri: https://github.com/7a6163/mitake_sms
178
+ source_code_uri: https://github.com/7a6163/mitake_sms
179
+ changelog_uri: https://github.com/7a6163/mitake_sms/blob/main/CHANGELOG.md
180
+ rdoc_options: []
181
+ require_paths:
182
+ - lib
183
+ required_ruby_version: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: 2.6.0
188
+ required_rubygems_version: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ requirements: []
194
+ rubygems_version: 3.6.7
195
+ specification_version: 4
196
+ summary: A Ruby client for Mitake SMS API
197
+ test_files: []