coolsms-rb 0.1.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
+ SHA1:
3
+ metadata.gz: ae1b50d864ab1b4d4b4ac03478d952f4352adb87
4
+ data.tar.gz: 1cb94bd102771d5f40911562323bf7768d05c493
5
+ SHA512:
6
+ metadata.gz: fbb32cbaf340383b5ab41c94556db2ba84b7ca6fae647affa54a96a80b64d68d42f3b19dd87c79be7009e30c998899ce4987fc9e2fc5afe166ca7b296481e1ca
7
+ data.tar.gz: 3ee5984a9ba01744970d3063d8ea06ce91c8c8d1fa457644daaa002941bc37792505b4465c5438a9b435c6cb314aa307bb0300f72e32441fdd5ff34b48ea3958
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Frograms, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # Coolsms
2
+
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ task :default => :test
5
+
6
+ require 'rake/testtask'
7
+
8
+ Rake::TestTask.new(:test) do |test|
9
+ test.libs << 'test'
10
+ test.verbose = true
11
+ end
@@ -0,0 +1,32 @@
1
+ module Coolsms
2
+ class Base
3
+ attr_accessor :attributes, :retrieved
4
+ attr_reader :response
5
+
6
+ def retrieve
7
+ self
8
+ ensure
9
+ @retrieved = true
10
+ end
11
+
12
+ def [](key)
13
+ value = attributes[key]
14
+ if value.nil? && !retrieved
15
+ retrieve
16
+ attributes[key]
17
+ else
18
+ value
19
+ end
20
+ end
21
+
22
+ def id
23
+ attributes[:id]
24
+ end
25
+
26
+ def refresh!
27
+ @attributes = {id: attributes[:id]}
28
+ @retrieved = false
29
+ retrieve
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,4 @@
1
+ module Coolsms
2
+ class Error < StandardError; end
3
+ class Uninitialized < Error; end
4
+ end
@@ -0,0 +1,63 @@
1
+ module Coolsms
2
+ class Finder < Base
3
+ def initialize(conditions_hash = {})
4
+ @attributes = conditions_hash.with_indifferent_access
5
+ end
6
+
7
+ def page=(num)
8
+ attributes[:page] = num
9
+ end
10
+
11
+ def api
12
+ @api = Coolsms::RestApi::Sent.new
13
+ @api.count = attributes[:per]
14
+ @api.page = attributes[:page]
15
+ @api.rcpt = attributes[:recipient_number]
16
+ @api.start = attributes[:accepted_from]
17
+ @api.end = attributes[:accepted_to]
18
+ @api.status = attributes[:status]
19
+ @api.resultcode = attributes[:result_code]
20
+ @api.notin_resultcode = attributes[:not_in_result_code]
21
+ @api.mid = attributes[:message_id]
22
+ @api.gid = attributes[:group_id]
23
+ @api
24
+ end
25
+
26
+ def retrieve
27
+ @response = api.call
28
+ attributes.update(@response.body.with_indifferent_access)
29
+ attributes[:data].map! do |msg_hash|
30
+ msg_hash[:id] = msg_hash.delete(:message_id)
31
+ Coolsms::Message.new(msg_hash)
32
+ end
33
+ super
34
+ end
35
+
36
+ def data; self[:data] end
37
+ def list_count; self[:list_count] end
38
+ def total_count; self[:total_count] end
39
+ def page; self[:page] end
40
+
41
+ def has_next?
42
+ (((page - 1) * list_count) + data.size) < total_count
43
+ end
44
+
45
+ def has_prev?
46
+ page > 1
47
+ end
48
+
49
+ alias_method :__dupp, :dup
50
+ def dup
51
+ duplicated = __dupp
52
+ duplicated.instance_variable_set(:@response, nil)
53
+ duplicated.instance_variable_set(:@retrieved, nil)
54
+ duplicated
55
+ end
56
+
57
+ def next_page
58
+ finder = self.dup
59
+ finder.page = page + 1
60
+ finder
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,32 @@
1
+ module Coolsms
2
+ class Group
3
+ attr_reader :id, :conditions_hash
4
+
5
+ def initialize(id, conditions_hash = {})
6
+ @id = id
7
+ @arr = []
8
+ @conditions_hash = conditions_hash.with_indifferent_access
9
+ end
10
+
11
+ def page(num)
12
+ @arr[num] ||= Finder.new(conditions_hash.merge(group_id: id))
13
+ end
14
+
15
+ def all
16
+ return @all if @all
17
+ recursive_next(1)
18
+ @all = @arr.map(&:data).flatten
19
+ end
20
+
21
+ def first
22
+ page(1).data.first
23
+ end
24
+
25
+ private
26
+
27
+ def recursive_next(num)
28
+ n = page(num).retrieve
29
+ recursive_next(num + 1) if n.has_next?
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,80 @@
1
+ module Coolsms
2
+ class Message < Base
3
+ attr_reader :send_api, :send_response
4
+
5
+ STATUSES = {
6
+ :accepted => '0',
7
+ :sending => '1',
8
+ :reported => '2'
9
+ }
10
+ INVERTED_STATUSES = STATUSES.invert
11
+
12
+ class EmptyMessage < Coolsms::Error; end
13
+ class AlreadySent < Coolsms::Error; end
14
+
15
+ def initialize(attrs_hash = {})
16
+ @attributes = {}.with_indifferent_access
17
+ assign_data(attrs_hash)
18
+ end
19
+
20
+ def from=(val); attributes[:from] = val end
21
+ def from; attributes[:from] || Coolsms.default_from end
22
+
23
+ def text=(val); attributes[:text] = val end
24
+
25
+ def api
26
+ return @api if @api
27
+ raise Uninitialized, 'Message id not defined' if attributes[:id].blank?
28
+ @api = Coolsms::RestApi::Sent.new
29
+ @api.mid = id
30
+ @api
31
+ end
32
+
33
+ def send(*to)
34
+ raise EmptyMessage if @attributes[:text].blank?
35
+ raise AlreadySent if @send_api || retrieved
36
+ if self[:text].bytes.size <= 90
37
+ @send_api = Coolsms::RestApi::Send.new(self[:text], from ,to)
38
+ else
39
+ @send_api = Coolsms::RestApi::Send.new(self[:text], from, to)
40
+ @send_api.subject = @attributes[:subject]
41
+ @send_api.type = :LMS
42
+ end
43
+ @send_response = @send_api.call
44
+ attributes[:group_id] = send_response.body['group_id']
45
+ @send_response
46
+ end
47
+
48
+ def assign_data(data_hash)
49
+ data_hash = data_hash.with_indifferent_access
50
+ data_hash[:accepted_at] = Coolsms::TIMEZONE.parse(data_hash.delete(:accepted_time)) if data_hash[:accepted_time]
51
+ data_hash[:sent_at] = Coolsms::TIMEZONE.parse(data_hash.delete(:sent_time)) if data_hash[:sent_time]
52
+ data_hash[:scheduled_at] = Coolsms::TIMEZONE.parse(data_hash.delete(:scheduled_time)) if data_hash[:scheduled_time]
53
+ data_hash[:status] = INVERTED_STATUSES[data_hash[:status]]
54
+ attributes.update(data_hash)
55
+ end
56
+
57
+ def retrieve
58
+ @response = api.call
59
+ data = (@response.body[:data] && @response.body[:data].first) || {}
60
+ assign_data(data)
61
+ super
62
+ end
63
+
64
+ def group
65
+ Coolsms::Group.new(group_id)
66
+ end
67
+
68
+ def type; self[:type] end
69
+ def accepted_at; self[:accepted_at] end
70
+ def recipient_number; self[:recipient_number] end
71
+ def group_id; self[:group_id] end
72
+ def result_code; self[:result_code] end
73
+ def result_message; self[:result_message] end
74
+ def sent_at; self[:sent_at] end
75
+ def text; self[:text] end
76
+ def carrier; self[:carrier] end
77
+ def scheduled_at; self[:scheduled_at] end
78
+ def status; self[:status] end
79
+ end
80
+ end
@@ -0,0 +1,95 @@
1
+ module Coolsms
2
+ class RestApi
3
+ class Error < Coolsms::Error
4
+ class << self
5
+ def status; 31000999 end
6
+ def http_status; 500 end
7
+ end
8
+
9
+ attr_accessor :api
10
+
11
+ def initialize(message = nil, cause = $!)
12
+ if message.is_a?(Hash) && message[:api]
13
+ @api = message.delete(:api)
14
+ end
15
+ super(message, cause)
16
+ end
17
+ end
18
+
19
+ class Unimplemented < Error; end
20
+
21
+ class ClientError < Error
22
+ class << self
23
+ def status; 31000990 end
24
+ def http_status; 500 end
25
+ end
26
+ end
27
+
28
+ class RequestError < Error
29
+ class << self
30
+ def status; 31000100 end
31
+ def http_status; 500 end
32
+ end
33
+ end
34
+
35
+ class ResponseError < RequestError
36
+ class << self
37
+ def status; 31000500 end
38
+ def http_status; 500 end
39
+ end
40
+
41
+ attr_accessor :status, :headers, :body
42
+
43
+ def initialize(message = nil, cause = $!)
44
+ res = message
45
+ res = message.delete(:response) if message.is_a?(Hash) && message[:response]
46
+
47
+ case res
48
+ when Faraday::Response then
49
+ self.status = res.status
50
+ self.headers = res.headers
51
+ self.body = res.body
52
+ when Faraday::Env then
53
+ self.status = res.status
54
+ self.headers = res.response_headers
55
+ self.body = res.body
56
+ when Faraday::Error::ClientError then
57
+ self.status = res[:status]
58
+ self.headers = res[:headers]
59
+ self.body = res[:body]
60
+ end
61
+
62
+ super(message, cause)
63
+ end
64
+ end
65
+
66
+ class InvalidJson < ResponseError
67
+ class << self
68
+ def status; 31000510 end
69
+ def http_status; 500 end
70
+ end
71
+ end
72
+
73
+ class EmptyResult < ResponseError
74
+ class << self
75
+ def status; 31000520 end
76
+ def http_status; 500 end
77
+ end
78
+ end
79
+
80
+ # http://www.coolsms.co.kr/REST_API#Authentication
81
+ class WrongResponseStatus < ResponseError
82
+ class << self
83
+ def status; 31000530 end
84
+ def http_status; 500 end
85
+ end
86
+ end
87
+
88
+ class InvalidResultCode < WrongResponseStatus
89
+ class << self
90
+ def status; 31000540 end
91
+ def http_status; 500 end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,12 @@
1
+ module Coolsms
2
+ class RestApi
3
+ class FaradayErrorHandler < Faraday::Response::Middleware
4
+ # Override this to modify the environment after the response has finished.
5
+ # Calls the `parse` method if defined
6
+ def on_complete(env)
7
+ # env.body = parse(env.body) if respond_to?(:parse) && env.parse_body?
8
+ raise Coolsms::RestApi::InvalidResultCode, {response: env} if env.body['result_code'] != '00'
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ FaradayMiddleware::ParseJson.dependency do
2
+ require 'oj' unless defined?(::Oj)
3
+ end
4
+
5
+ FaradayMiddleware::ParseJson.define_parser do |body|
6
+ ::Oj.load(body || '')
7
+ end
@@ -0,0 +1,69 @@
1
+ module Coolsms
2
+ class RestApi
3
+ # http://www.coolsms.co.kr/SMS_API
4
+ class Send < RestApi
5
+ NECESSARY_PARAMS = [:from, :to, :text]
6
+ OPTIONAL_PARAMS = [
7
+ :type,
8
+ :image, :image_encoding,
9
+ :refname,
10
+ :country,
11
+ :datetime,
12
+ :subject,
13
+ :charset,
14
+ :srk,
15
+ :mode,
16
+ :extension,
17
+ :delay,
18
+ :force_sms,
19
+ :os_platform,
20
+ :dev_lang,
21
+ :sdk_version,
22
+ :app_version
23
+ ]
24
+
25
+ attr_accessor *(NECESSARY_PARAMS + OPTIONAL_PARAMS)
26
+
27
+ class << self
28
+ def conn
29
+ @conn ||= Faraday.new(url: url) do |conn|
30
+ conn.use Coolsms::RestApi::FaradayErrorHandler
31
+ conn.response :json
32
+ conn.use :instrumentation
33
+ conn.use Faraday::Response::RaiseError
34
+ conn.adapter Coolsms.faraday_adapter || Faraday.default_adapter
35
+ end
36
+ end
37
+ end
38
+
39
+ def initialize(text, from, *to)
40
+ self.text = text
41
+ self.from = Coolsms.number_strip(from)
42
+ self.to = to
43
+ end
44
+
45
+ def to_params
46
+ params = auth_params
47
+ NECESSARY_PARAMS.each do |param|
48
+ params.update(param => send(param))
49
+ end
50
+ OPTIONAL_PARAMS.each do |param|
51
+ params.update(param => send(param)) if send(param)
52
+ end
53
+
54
+ to = Array(params[:to]).flatten
55
+ to = to.map do |num|
56
+ split= num.split(',')
57
+ split.map { |num2| Coolsms.number_strip(num2) }
58
+ end.flatten.uniq.join(',')
59
+ params[:to] = to
60
+
61
+ params
62
+ end
63
+
64
+ def call
65
+ conn.post '/sms/1.5/send', to_query
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,30 @@
1
+ module Coolsms
2
+ class RestApi::Sent < RestApi
3
+ OPTIONAL_PARAMS = [
4
+ :count,
5
+ :page,
6
+ :rcpt,
7
+ :start,
8
+ :end,
9
+ :status,
10
+ :resultcode,
11
+ :notin_resultcode,
12
+ :mid,
13
+ :gid
14
+ ]
15
+
16
+ attr_accessor *OPTIONAL_PARAMS
17
+
18
+ def to_params
19
+ params = auth_params
20
+ OPTIONAL_PARAMS.each do |param|
21
+ params.update(param => send(param)) if send(param)
22
+ end
23
+ params
24
+ end
25
+
26
+ def call
27
+ conn.get '/sms/1.5/sent', to_params
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,81 @@
1
+ require 'active_support/core_ext/object/to_query'
2
+
3
+ module Coolsms
4
+ class RestApi
5
+ cattr_writer :url,
6
+ :api_key, :api_secret
7
+
8
+ class << self
9
+ def url; @@url || Coolsms.url end
10
+ def api_key; @@api_key || Coolsms.api_key end
11
+ def api_secret; @@api_secret || Coolsms.api_secret end
12
+
13
+ def conn=(conn)
14
+ @conn = conn
15
+ end
16
+
17
+ def conn
18
+ @conn ||= Faraday.new(url: url) do |conn|
19
+ conn.response :json
20
+ conn.use :instrumentation
21
+ conn.use Faraday::Response::RaiseError
22
+ conn.adapter Coolsms.faraday_adapter || Faraday.default_adapter
23
+ end
24
+ end
25
+ end
26
+
27
+ def conn
28
+ self.class.conn
29
+ end
30
+
31
+ def call
32
+ raise Unimplemented, {desc: self.class.name}
33
+ end
34
+
35
+ def callback
36
+ # do not call response, use @response
37
+ end
38
+
39
+ def auth_params
40
+ timestamp = Time.now.to_i
41
+ salt = SecureRandom.hex
42
+ hmac_data = timestamp.to_s + salt.to_s
43
+ signature = OpenSSL::HMAC.hexdigest('md5', self.class.api_secret, hmac_data)
44
+ {
45
+ api_key: self.class.api_key,
46
+ timestamp: timestamp,
47
+ salt: salt,
48
+ signature: signature
49
+ }
50
+ end
51
+
52
+ def to_params
53
+ auth_params
54
+ end
55
+
56
+ def to_query
57
+ to_params.to_query
58
+ end
59
+
60
+ def response
61
+ @response ||= call
62
+ callback
63
+ @response
64
+ rescue Oj::ParseError
65
+ raise Coolsms::RestApi::InvalidJson, api: self
66
+ rescue Faraday::Error::ClientError => e
67
+ raise Coolsms::RestApi::ResponseError, {api: self, response: e}
68
+ rescue Coolsms::RestApi::Error => e
69
+ e.api = self
70
+ raise e
71
+ rescue
72
+ raise Coolsms::RestApi::Error, api: self
73
+ end
74
+ end
75
+ end
76
+
77
+ require 'coolsms/rest_api/errors'
78
+ require 'coolsms/rest_api/faraday_json_parser'
79
+ require 'coolsms/rest_api/faraday_error_handler'
80
+ require 'coolsms/rest_api/send'
81
+ require 'coolsms/rest_api/sent'
@@ -0,0 +1,3 @@
1
+ module Coolsms
2
+ VERSION = '0.1.0'
3
+ end
data/lib/coolsms-rb.rb ADDED
@@ -0,0 +1 @@
1
+ require 'coolsms'
data/lib/coolsms.rb ADDED
@@ -0,0 +1,58 @@
1
+ require 'logger'
2
+ require 'active_support/core_ext/object/blank'
3
+ require 'active_support/core_ext/hash/indifferent_access'
4
+ require 'active_support/core_ext/module/attribute_accessors'
5
+ require 'active_support/core_ext/class/attribute_accessors'
6
+ require 'active_support/core_ext/array/extract_options'
7
+ require 'active_support/values/time_zone'
8
+ require 'oj'
9
+ require 'faraday'
10
+ require 'faraday_middleware'
11
+ require 'coaster'
12
+ require 'awesome_print'
13
+
14
+ module Coolsms
15
+ mattr_accessor :api_key, :api_secret,
16
+ :default_from
17
+
18
+ mattr_accessor :url
19
+ @@url = 'https://api.coolsms.co.kr'
20
+
21
+ mattr_accessor :logger
22
+ @@logger = Logger.new('log/sms.log')
23
+
24
+ mattr_accessor :faraday_adapter
25
+
26
+ NUMBER_STRIP_REGEX = /[^\d]/
27
+ TIMEZONE = ActiveSupport::TimeZone.new('Seoul')
28
+
29
+ class << self
30
+ def number_strip(str)
31
+ str.gsub(NUMBER_STRIP_REGEX, '')
32
+ end
33
+
34
+ def configure
35
+ yield(self)
36
+ end
37
+
38
+ def message(text, *to)
39
+ options = to.extract_options!
40
+ options[:text] = text
41
+ options[:from] ||= default_from
42
+ msg = Coolsms::Message.new(options)
43
+ if block_given?
44
+ yield(msg)
45
+ else
46
+ msg.send(*to)
47
+ end
48
+ msg
49
+ end
50
+ end
51
+ end
52
+
53
+ require 'coolsms/errors'
54
+ require 'coolsms/rest_api'
55
+ require 'coolsms/base'
56
+ require 'coolsms/finder'
57
+ require 'coolsms/message'
58
+ require 'coolsms/group'
@@ -0,0 +1,8 @@
1
+ Coolsms.configure do |cool|
2
+ cool.api_key = 'api_key'
3
+ cool.api_secret = 'api_secret'
4
+ cool.default_from = 'default_sender_number'
5
+ cool.faraday_adapter = :net_http
6
+ end
7
+
8
+ COOLSMS_TEST_RECEIVERS = ['test_receiver_number_1', 'test_receiver_number_2']
@@ -0,0 +1,11 @@
1
+ ENV['DEBUG'] = 'true'
2
+
3
+ require 'minitest'
4
+ require 'forgery'
5
+ require 'pry'
6
+
7
+ require 'rubygems'
8
+ require 'bundler/setup'
9
+ require 'coolsms'
10
+
11
+ require 'init'
data/test/test_send.rb ADDED
@@ -0,0 +1,47 @@
1
+ require 'test_helper'
2
+ require 'minitest/autorun'
3
+
4
+ module Coolsms
5
+ class TestSend < Minitest::Test
6
+ def test_single
7
+ skip('캐시가 차감되서 막아놓음')
8
+ msg = Coolsms::Message.new
9
+ msg.text = '안녕, 세계 ㅎㅎ'
10
+ result = msg.send(COOLSMS_TEST_RECEIVERS.first)
11
+ assert_equal 1, result.body['success_count']
12
+ sleep(10) # 보내는데 걸리는 시간
13
+ sent = msg.group.first
14
+ assert_equal '00', sent.result_code
15
+ end
16
+
17
+ def test_single_class_method
18
+ skip('캐시가 차감되서 막아놓음')
19
+ msg = Coolsms.message("안녕이라고\n말하지마", COOLSMS_TEST_RECEIVERS.first)
20
+ sleep(10) # 보내는데 걸리는 시간
21
+ sent = msg.group.first
22
+ assert_equal '00', sent.result_code
23
+ end
24
+
25
+ def test_wrong_number
26
+ skip('오래걸려서 스킵')
27
+ msg = Coolsms::Message.new
28
+ msg.text = '거기누구없소'
29
+ result = msg.send('01911')
30
+ assert_equal 1, result.body['success_count']
31
+ sleep(30) # 보내는데 걸리는 시간
32
+ sent = msg.group.first
33
+ assert_equal '58', sent.result_code
34
+ end
35
+
36
+ def test_long_single
37
+ msg = Coolsms::Message.new
38
+ msg.text = Forgery(:lorem_ipsum).words(50)
39
+ result = msg.send(COOLSMS_TEST_RECEIVERS.first)
40
+ assert_equal 1, result.body['success_count']
41
+ sleep(10)
42
+ sent = msg.group.first
43
+ assert_equal '00', sent.result_code
44
+ assert_equal 'LMS', sent.type
45
+ end
46
+ end
47
+ end
metadata ADDED
@@ -0,0 +1,292 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: coolsms-rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - buzz jung
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.9.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.9.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: oj
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.9'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: tzinfo
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.3.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.3.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: faraday_middleware
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.10.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.10.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: awesome_print
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: coaster
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.1.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.1.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: bundler
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.8'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.8'
139
+ - !ruby/object:Gem::Dependency
140
+ name: pry-stack_explorer
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.4'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.4'
153
+ - !ruby/object:Gem::Dependency
154
+ name: pry-byebug
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '3.0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '3.0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: minitest
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '5.0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '5.0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: mocha
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '1.0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '1.0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: shoulda
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '3.0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '3.0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: shoulda-context
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '1.0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '1.0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: forgery
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: '0.6'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: '0.6'
237
+ description: CoolSMS Ruby Client. under construction...
238
+ email:
239
+ - buzz@frograms.com
240
+ executables: []
241
+ extensions: []
242
+ extra_rdoc_files: []
243
+ files:
244
+ - LICENSE
245
+ - README.md
246
+ - Rakefile
247
+ - lib/coolsms-rb.rb
248
+ - lib/coolsms.rb
249
+ - lib/coolsms/base.rb
250
+ - lib/coolsms/errors.rb
251
+ - lib/coolsms/finder.rb
252
+ - lib/coolsms/group.rb
253
+ - lib/coolsms/message.rb
254
+ - lib/coolsms/rest_api.rb
255
+ - lib/coolsms/rest_api/errors.rb
256
+ - lib/coolsms/rest_api/faraday_error_handler.rb
257
+ - lib/coolsms/rest_api/faraday_json_parser.rb
258
+ - lib/coolsms/rest_api/send.rb
259
+ - lib/coolsms/rest_api/sent.rb
260
+ - lib/coolsms/version.rb
261
+ - test/init.rb.sample
262
+ - test/test_helper.rb
263
+ - test/test_send.rb
264
+ homepage: http://github.com/frograms/coolsms-rb
265
+ licenses:
266
+ - MIT
267
+ metadata: {}
268
+ post_install_message:
269
+ rdoc_options: []
270
+ require_paths:
271
+ - lib
272
+ required_ruby_version: !ruby/object:Gem::Requirement
273
+ requirements:
274
+ - - ">="
275
+ - !ruby/object:Gem::Version
276
+ version: '0'
277
+ required_rubygems_version: !ruby/object:Gem::Requirement
278
+ requirements:
279
+ - - ">="
280
+ - !ruby/object:Gem::Version
281
+ version: '0'
282
+ requirements: []
283
+ rubyforge_project:
284
+ rubygems_version: 2.4.8
285
+ signing_key:
286
+ specification_version: 4
287
+ summary: CoolSMS Ruby Client
288
+ test_files:
289
+ - test/init.rb.sample
290
+ - test/test_helper.rb
291
+ - test/test_send.rb
292
+ has_rdoc: